docs/TROUBLESHOOTING.md · erreurs réelles du lab
Règle numéro 1 : quand OpenCode se comporte mal après le login, commencer par inspecter les claims du jeton d’accès — le symptôme y est presque toujours déjà écrit.
Diagnostics rapides
# Pile
docker compose ps
curl -sI http://127.0.0.1:8080/mcp | head -15
curl -s http://127.0.0.1:8080/.well-known/oauth-protected-resource/mcp
# OpenCode
opencode mcp list
ss -ltnp | grep 19876 || echo "callback port free"
# Jeton (après une tentative de login)
python3 - <<'PY'
import json
from pathlib import Path
from jose import jwt
p = Path.home() / ".local/share/opencode/mcp-auth.json"
if not p.exists():
print("no mcp-auth.json")
else:
at = json.loads(p.read_text())["ords-mcp"]["tokens"]["accessToken"]
c = jwt.get_unverified_claims(at)
print("aud ", c.get("aud"))
print("roles2 ", c.get("roles2"))
print("permissions", c.get("permissions"))
print("scope ", c.get("scope"))
print("sub ", c.get("sub"))
PY
# Erreurs JWT côté ORDS
docker logs ords 2>&1 | grep -iE 'JWT|Role Claim|JWK|Forbidden' | tail -20
Erreurs Auth0 (navigateur)
Cause : la redirection d’OpenCode n’est pas dans les Allowed Callback URLs de l’app Native.
Correctif : ajouter exactement :
http://127.0.0.1:19876/mcp/oauth/callback
(et http://localhost:19876/mcp/oauth/callback si besoin). Le chemin doit inclure /mcp/oauth/callback.
Cause : app en Machine to Machine, ou grant Authorization Code désactivé.
Correctif : type d’application = Native (ou SPA) ; Advanced → Grant Types → Authorization Code (+ Refresh Token) → Save. Passer M2M → Native désactive Client Credentials sur cette app — normal pour OpenCode.
https://my-proxy/mcp mais le client utilise https://my-proxy/ords/mcpCause : le proxy mappe https://my-proxy/ords/ → http://ords (en enlevant le préfixe).
MCP est une ressource à la racine de l’hôte (/mcp), pas sous standalone.context.path.
ORDS reconstruit la ressource depuis Host + /mcp. Il n’existe pas de réglage de préfixe public, et l’audience ne réécrit pas les URL annoncées.
Correctif : servir MCP sur un hôte dédié (https://ords-mcp.company.com/mcp)
sans enlever de préfixe. Voir reverse proxy.
Cause : Auth0 n’a pas d’API dont l’Identifier est exactement cette chaîne.
OpenCode envoie resource=http://127.0.0.1:8080/mcp ; une API nommée seulement https://ords.lab/mcp ne correspond pas.
Correctif : créer l’API avec l’Identifier exactement http://127.0.0.1:8080/mcp
(http, 127.0.0.1, port 8080, chemin /mcp). Mettre AUTH0_AUDIENCE et l’audience ORDS à la même valeur ;
recréer le volume ords-config si ORDS avait l’ancienne audience. Le texte côté Auth0 ressemble à :
Service not enabled within domain : http://127.0.0.1:8080/mcp.
Cause : l’app Native n’active pas le Resource Owner Password.
Correctif : normal pour OpenCode (qui utilise le code d’autorisation). Pour les tests
scripts/test_auth0.py : soit activer le grant password sur une app dev uniquement (déconseillé en prod), soit utiliser les jetons OpenCode / une app confidentielle séparée.
Erreurs CLI OpenCode
Causes fréquentes : 1) port 19876 déjà pris par un autre processus
opencode ; 2) le serveur de callback n’a pas pu démarrer ; 3) navigateur fermé avant la fin du CLI.
Correctif :
ss -ltnp | grep 19876
kill <pid> # le opencode qui tient le port
rm -f ~/.local/share/opencode/mcp-auth.json
set -a && source .env && set +a
opencode mcp auth ords-mcp
Signification : l’échange du code a souvent réussi (vérifier mcp-auth.json
pour un accessToken), mais OpenCode ne peut pas utiliser MCP. Réponse ORDS typique avec ce jeton : 403 Forbidden.
| Claim | Mauvais | Bon |
|---|---|---|
roles2 | [] ou absent | ["POOL.FIN"] |
permissions | [] | ["urn:oracle:dbtools:ords:mcpserver:all"] |
Correctif :
POOL.FIN / POOL.HR)http://127.0.0.1:8080/mcproles2opencode mcp logout && opencode mcp auth à nouveauUne fois corrigé, opencode mcp list affiche connected (OAuth).
opencode mcp list → needs authentication (après un auth réussi)Identique au cas ci-dessus : le jeton existe mais ORDS le refuse (401/403). Inspecter les claims et les logs ORDS.
Normal. Configurer via Applications → APIs (resource server) et Roles → Permissions — pas la liste M2M des apps Native.
Erreurs ORDS (logs / HTTP)
JSON Web Token Validation Error: Unsupported Role Claim Format / Missing Role Claim
Cause : le jeton n’a pas de tableau roles2 exploitable (ou ORDS pointe toujours sur un mauvais claim).
Correctif : l’Action doit faire setCustomClaim("roles2", roles) — pas
"roles" ; MCP_ROLE_CLAIM=/roles2 et recréer la config ORDS si besoin ; se reloguer après le déploiement de l’Action.
Causes : signature invalide, mauvais iss/aud, JWKS injoignable, claim de rôle absent.
Correctif :
docker exec ords curl -fsSI https://$AUTH0_DOMAIN/.well-known/jwks.jsondns: 1.1.1.1 / 8.8.8.8 si le DNS hôte échoue dans les conteneursaud doit être http://127.0.0.1:8080/mcpiss avec le slash finalCause (ce lab) : JWT valide mais pas de scope/permission MCP et/ou rôle non autorisé pour un pool.
Correctif : ajouter la permission API au rôle Auth0 ; s’assurer que roles2
contient POOL.HR et/ou POOL.FIN ; se ré-authentifier.
Cause : le conteneur ORDS ne résout pas ou n’atteint pas Auth0.
Correctif : vérifier le DNS/réseau du conteneur ; le compose lab définit un DNS public sur
ords. Redémarrer ords.
Correctif : définir AUTH0_DOMAIN dans .env ; docker compose up -d ords.
Base / données
Cause : sql/01_lab_schemas.sql ne s’exécute qu’à la première création du volume de données Oracle.
Correctif :
docker compose down -v
docker compose up -d --build
ou appliquer le SQL manuellement sur FREEPDB1 en tant que SYS.
Dérive de config
docker compose stop ords && docker compose rm -f ords
docker volume rm ords_ords-config
docker compose up -d ords
scripts/configure-mcp.sh s’exécute à chaque démarrage et applique .env.
Checklist mentale
http://127.0.0.1:8080/mcproles2.env : audience + /roles2opencode mcp authroles2 et permissionsopencode mcp list → connected (OAuth)