fix(walkthrough): block unauthenticated providers with a friendly refusal

When the walkthrough small model resolves to a provider with no usable
login, readiness was still ready and generate returned a raw 500 message.
Refuse up front with no-provider-login and surface a blocker instead.

Closes openchamber/openchamber#2607

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
This commit is contained in:
Cursor Agent
2026-08-04 11:29:58 +00:00
co-authored by Serhii Dziupin
parent f47110c66f
commit abb396e080
22 changed files with 286 additions and 12 deletions
@@ -333,6 +333,12 @@ function computeReadiness({ model, digest, files, fileCount, hunkCount, generate
return { ready: false, reason, model, generatedFileCount };
}
// A resolved override/config model can still have no usable login. Refuse up
// front so the panel does not look ready and then dump a raw auth error.
if (model.hasLogin === false) {
return { ready: false, reason: 'no-provider-login', model };
}
// Built with the same language the generation would use: the instruction is
// part of the prompt, so a readiness answer computed without it would be
// measuring a request nobody is going to send.
@@ -392,6 +398,13 @@ async function runGeneration({ directory, source, repoRoot, key, force, explicit
if (!model) {
throw fail('No model is available — sign in to a provider first', 404, { code: 'no-model' });
}
if (model.hasLogin === false) {
throw fail(
`No OpenCode login found for provider "${model.providerID}" — sign in or choose a different model`,
401,
{ code: 'no-provider-login', model },
);
}
const { digest, files, idByAlias, fileCount, hunkCount, generatedFileCount } = await loadCurrentDiff(directory, source, deps);
setStage(repoRoot, key, 'asking');
@@ -494,6 +507,9 @@ async function runGeneration({ directory, source, repoRoot, key, force, explicit
if (error?.code === 'output-exhausted') {
return fail(error.message, 409, { code: 'output-exhausted', model });
}
if (error?.code === 'no-provider-login') {
return fail(error.message, 401, { code: 'no-provider-login', model });
}
return null;
};