{"record":{"id":"9993b19d9589c6aa","repo":"xai-org/grok-build","slug":"external-auth-provider-command-e","errorCode":null,"errorMessage":"external auth provider `{command}`: {e}","messagePattern":"external auth provider `(.+?)`: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codegen/xai-grok-shell/src/auth/flow.rs","lineNumber":246,"sourceCode":"                    }\n                }\n            }\n        }))\n    } else {\n        None\n    };\n    let output = tokio::time::timeout(\n        std::time::Duration::from_secs(300),\n        child.wait_with_output(),\n    )\n    .await\n    .map_err(|_| anyhow::anyhow!(\"external auth provider `{command}` timed out after 300s\"))?\n    .map_err(|e| anyhow::anyhow!(\"external auth provider `{command}` IO error: {e}\"))?;\n    if let Some(task) = stderr_task {\n        let _ = task.await;\n    }\n    let mut auth = parse_output(&output)\n        .map_err(|e| anyhow::anyhow!(\"external auth provider `{command}`: {e}\"))?;\n    let principal_policy =\n        crate::auth::oidc::login_principal_policy(auth_manager.grok_com_config());\n    crate::auth::oidc::enforce_login_principal(\n        principal_policy.as_ref(),\n        crate::auth::oidc::peek_access_token_principal_id(&auth.key).as_deref(),\n    )?;\n    match (over_stale_credential, auth_manager.current_or_expired()) {\n        (true, Some(prev)) => auth.carry_user_profile_from(&prev),\n        _ => auth_manager.enrich_auth_inline(&mut auth).await,\n    }\n    let auth = auth_manager\n        .update(auth)\n        .await\n        .map_err(|e| anyhow::anyhow!(\"failed to save external auth credentials: {e}\"))?;\n    tracing::info!(\n        user_id = %auth.user_id,\n        email = ?auth.email,\n        \"auth: external provider login complete\"","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-grok-shell/src/auth/flow.rs#L228-L264","documentation":"The provider process ran and produced output, but parse_output() could not turn that output into credentials. The parse error text (from token_output parsing, e.g. 'exited with …', 'produced no output on stdout', 'produced JSON that is not a token payload') is embedded after the command name.","triggerScenarios":"The provider exits non-zero, prints nothing to stdout, prints non-JSON non-token text, prints JSON that fails ExternalAuthOutput deserialization, or prints JSON with an empty access_token during any external-provider login flow.","commonSituations":"Provider prints diagnostics to stdout instead of stderr; provider returns an error object like {\"error\":\"expired\"} instead of a token payload; provider version changed its output schema (missing access_token or refresh_token fields); wrong credentials cause an HTML/text error page on stdout.","solutions":["Run the provider manually and inspect stdout; move human-readable diagnostics to stderr and keep stdout strictly the token.","Ensure the JSON payload includes a non-empty `access_token` (and refresh token only inside JSON, not bare) matching the published contract.","Update the provider to the version matching the shell's expected ExternalAuthOutput schema.","Check provider exit codes: a non-zero exit is reported as 'exited with N'; fix whatever makes the provider fail."],"exampleFix":"// before (provider prints prose + JSON to stdout)\necho \"fetching token...\"; echo \"$JSON\"\n// after\necho \"fetching token...\" >&2; printf '%s' \"$JSON\"","handlingStrategy":"validation","validationCode":"const out = execSync(provider_cmd, { encoding: 'utf8' });\nif (out.trim().startsWith('{')) {\n  const j = JSON.parse(out);\n  if (typeof j.access_token !== 'string' || !j.access_token.trim()) {\n    throw new Error('provider JSON is not a valid token payload');\n  }\n}","typeGuard":"function isTokenPayload(v) {\n  return typeof v === 'object' && v !== null &&\n    typeof v.access_token === 'string' && v.access_token.trim().length > 0;\n}","tryCatchPattern":"match run_auth_flow(...).await {\n    Err(e) if e.to_string().contains(\": produced\") || e.to_string().contains(\"exited with\") => {\n        eprintln!(\"Provider output violates the token contract — inspect its stdout\");\n    }\n    other => other?,\n}","preventionTips":["Keep stdout strictly the token/JSON; log to stderr","Test the provider against the ExternalAuthOutput schema in CI","Exit non-zero on provider-side errors instead of printing JSON errors","Version the contract and check compatibility on provider upgrades"],"tags":["auth","external-provider","output-parsing","contract"],"backgroundTag":"invalid-token-payload","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}