AI Connect/Reference/Dépannage
Dépannage
Diagnostic symptôme par symptôme : erreurs du constructeur, AuthError, états des connecteurs, ensembles vides de capacités, échecs de dispatch des adaptateurs, timeouts et diagnostics pour le support.
Diagnostiquez par symptôme. Chaque section fait correspondre un comportement observé à sa cause et à sa correction.
Le constructeur lève une exception avant toute requête
Erreur de préfixe pour appId ou apiKey. Utilisez l'ID public et la clé secrète dans les champs appropriés :
const vinkius = new Vinkius({
appId: 'vk_app_...',
apiKey: 'vk_app_sk_...',
});L'ID public de l'application doit commencer par vk_app_, mais pas par vk_app_sk_. La clé doit commencer par vk_app_sk_.
No global fetch found. Utilisez Node.js 18 ou version ultérieure, un runtime avec fetch global, ou transmettez une implémentation compatible au moyen de l'option fetch du constructeur.
Invalid externalId. Utilisez l'ID utilisateur de votre application, et non un identifiant vk_app_user_.... Il doit comporter de 1 à 255 caractères et ne peut contenir ni espace, ni /, ni barre oblique inversée.
Les requêtes lèvent AuthError
Une réponse HTTP 401 ou 403 est convertie en AuthError.
- Vérifiez que les variables d'environnement ont été chargées dans le processus serveur.
- Vérifiez que l'Application Key appartient à l'App ID et à l'environnement configurés.
- Remplacez une clé révoquée ou ayant fait l'objet d'une rotation.
- Vérifiez que le code de déploiement n'a pas interverti l'App ID et la clé.
- Enregistrez
requestIdlorsqu'il est présent, mais ne journalisez jamais la clé.
L'état du connecteur est not_connected
Un handle ne crée pas de connexion :
const connector = vinkius.user(externalId).connector('github');
console.log(await connector.status()); // may be 'not_connected'
await connector.connect();connect() effectue la requête de récupération ou création. credentials.status(), credentials.set(), disconnect() et les capabilities() limitées au connecteur lèvent ConnectorNotConnectedError tant qu'aucune connexion n'existe.
L'état du connecteur est needs_credentials
Lisez le schéma du catalogue, recueillez les valeurs requises dans votre flux serveur, puis enregistrez-les :
const schema = await connector.credentials.schema();
const state = await connector.credentials.set(values);
console.log(schema, state.configured);schema() peut s'exécuter avant la connexion, contrairement à set(). Comparez le nom des clés soumises au schéma et inspectez ValidationError.errors si le service les refuse. Les valeurs stockées ne sont pas renvoyées.
L'état du connecteur est disabled
La connexion existe, mais son état dans l'API n'est pas actif. Réécrire les identifiants peut ne pas modifier cette situation. Indiquez à l'utilisateur que la connexion ne peut pas s'exécuter, inspectez si nécessaire la réponse de connexion au moyen du client de bas niveau, ou remplacez la connexion conformément au flux de votre application.
user.capabilities() renvoie un ensemble vide
Un ensemble vide est valide. Inspectez le contexte et les filtres :
const user = vinkius.user(externalId);
const connectors = await user.connectors();
const capabilities = await user.capabilities({ include: ['github'] });
console.log({ connectors, count: capabilities.length });Vérifiez les points suivants dans l'ordre :
externalIdprovient bien de la session authentifiée voulue.- Le slug attendu apparaît dans
connectors(). - Son état dérivé est
ready. includeutilise le slug exact attendu par le service.excluden'a pas retiré le connecteur localement.- L'endpoint agrégé a réellement renvoyé des actions pour la connexion.
Le client convertit la réponse de l'endpoint ; il n'ajoute aucun filtre local sur l'état de préparation.
La recherche de capacité renvoie undefined
Inspectez les deux noms :
for (const capability of capabilities) {
console.log(capability.name, capability.rawName, capability.connector);
}Par défaut, le nom d'affichage possède un espace de noms, par exemple github__create_issue. findCapability() accepte le nom d'affichage ou le nom brut et renvoie la première correspondance. Lorsque des noms bruts entrent en collision, appelez d'abord forConnector(slug) ou utilisez le nom d'affichage avec espace de noms.
Si vous avez fourni namespaceCapability, vérifiez que sa sortie respecte les contraintes de nommage du fournisseur et reste unique ; les adaptateurs ne font respecter aucune de ces deux propriétés.
Une fonction de dispatch d'adaptateur lève Unknown capability
Transmettez le même tableau de capacités à la conversion et au dispatch, et conservez exactement le nom d'affichage renvoyé :
const tools = toOpenAITools(capabilities);
// Send tools to the model, then:
const result = await runOpenAIToolCall(capabilities, returnedCall);Les fonctions de dispatch OpenAI, Anthropic et Gemini comparent uniquement les noms d'affichage. Le dispatch JSON Schema accepte les noms d'affichage ou bruts, avec une ambiguïté sur la première correspondance pour les noms bruts dupliqués. Les noms de dispatch inconnus lèvent une simple Error, et non une VinkiusError.
Les arguments OpenAI deviennent inopinément {}
runOpenAIToolCall analyse call.function.arguments. Les chaînes vides, le JSON mal formé, la valeur JSON null et les primitives JSON sont tous convertis en {}. Validez ou journalisez la forme analysée dans votre propre boucle de modèle si les arguments mal formés doivent être refusés plutôt que tolérés.
L'exécution est résolue avec isError: true
La requête HTTP s'est terminée et la capacité a signalé l'échec de l'action. Inspectez le contenu renvoyé :
const result = await capability.execute(args, options);
if (result.isError) {
console.error(result.content.map((part) => part.text).join('\n'));
}N'attendez pas cette branche dans catch. Une boucle de fournisseur peut renvoyer le résultat au modèle, tandis qu'une route déterministe peut le convertir en réponse d'erreur applicative. Les adaptateurs à fabrique qui renvoient des chaînes perdent isError ; exécutez donc directement la capacité d'origine lorsque cette distinction est importante.
L'exécution a expiré ou a levé ConnectionError
Les lectures et les autres opérations répétables peuvent être réessayées automatiquement. L'exécution d'une capacité n'est réessayée que lorsque idempotencyKey n'est pas undefined :
if (!operationId) throw new Error('operationId is required');
await capability.execute(args, {
idempotencyKey: `create-issue:${operationId}`,
});Ne transmettez pas une clé vide : l'implémentation actuelle peut la classer comme répétable sans envoyer l'en-tête. Après un timeout sans clé valide, l'action externe peut avoir abouti ; réconciliez son état avant d'envoyer une nouvelle opération. Les fonctions de dispatch des adaptateurs ne peuvent transmettre ni clé d'idempotence ni signal ; utilisez l'exécution directe pour les effets de bord qui nécessitent ces contrôles.
Une erreur de débit ou de plan persiste
RateLimitErrorpeut fournirretryAfterMsune fois les nouvelles tentatives automatiques épuisées.QuotaErroretOverageErrorpeuvent fournirupgradeUrl; répéter la même opération ne modifie pas une limite de plan.- Le transport considère une réponse
429comme transitoire avant d'analyser son corps ; les requêtes répétables peuvent donc consommer leurs nouvelles tentatives avant une erreur de quota finale.
Les hooks n'affichent pas une erreur réseau
onResponse ne s'exécute qu'après une réponse HTTP. Un timeout ou une erreur réseau sans réponse ne l'invoque pas. onRequest s'exécute avant chaque tentative ; un journal de requête sans journal de réponse peut donc indiquer une erreur de transport. Les exceptions des hooks sont propagées sous leur forme d'origine. Veillez à ce que les hooks ne lèvent pas d'exception. Le SDK expurge une liste fixe de noms de champs exacts, et non toutes les clés personnalisées qui ressemblent à des secrets.
Recueillir les diagnostics pour le support
import { VinkiusError } from '@vinkius/connect';
if (error instanceof VinkiusError) {
console.error({
code: error.code,
status: error.status,
requestId: error.requestId,
connector: connector.slug,
occurredAt: new Date().toISOString(),
});
}Une erreur locale ou de transport peut ne pas avoir de requestId. N'incluez ni clés d'application, ni valeurs d'identifiants, ni en-têtes d'autorisation, ni error.details non examinés. Signalez les problèmes de sécurité de manière privée à security@vinkius.com ; consultez Security.
