{"record":{"id":"2ecd03c356c4d116","repo":"thedotmack/claude-mem","slug":"non-interactive-provider-validation-did-not-run","errorCode":null,"errorMessage":"Non-interactive provider validation did not run.","messagePattern":"Non-interactive provider validation did not run\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/npx-cli/commands/install.ts","lineNumber":1089,"sourceCode":"    if (!wrote) {\n      p.cancel('Could not save the local Anthropic Max configuration.');\n      process.exit(1);\n    }\n    saveClaudeMemEnv({\n      ANTHROPIC_API_KEY: '',\n      ANTHROPIC_BASE_URL: '',\n      ANTHROPIC_AUTH_TOKEN: '',\n    });\n    log.info('Disabled cloud sync and saved local Anthropic Max configuration.');\n    log.info('Configured claude-mem to use your logged-in Claude SDK account.');\n  };\n\n  let selectedProvider: ProviderChoice;\n  if (options.provider) {\n    selectedProvider = options.provider;\n  } else {\n    if (!isInteractive) {\n      throw new Error('Non-interactive provider validation did not run.');\n    }\n    const labels = buildProviderLabels();\n\n    // Multiselect gives both choices square controls. Exactly one provider is\n    // still required; selecting both re-opens the prompt instead of guessing.\n    while (true) {\n      const providerResult = await p.multiselect<ProviderChoice>({\n        message: PROVIDER_PROMPT_MESSAGE,\n        options: [\n          { value: 'cmem', label: labels.cmem, hint: labels.cmemHint },\n          { value: 'claude', label: labels.claude, hint: labels.claudeHint },\n        ],\n        // CMEM Pro pre-selected: it is the recommended path and the one the\n        // funnel is built around. Selecting it no longer means \"pay now\" —\n        // it opens the offer page to read first.\n        initialValues: ['cmem'],\n        required: true,\n      });","sourceCodeStart":1071,"sourceCodeEnd":1107,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/8bc631a71a487424b866756e43a6efa4574cc66b/src/npx-cli/commands/install.ts#L1071-L1107","documentation":"During install, if no --provider flag was supplied the command normally opens an interactive multiselect prompt to choose one. In a non-interactive environment (piped stdin, CI, no TTY) prompts cannot run, and if the earlier non-interactive provider validation did not populate a selection, the install throws this error rather than silently picking a provider.","triggerScenarios":"Running the installer non-interactively (e.g. `npx claude-mem install < /dev/null`, CI job, scripted run) without passing --provider, so options.provider is undefined and isInteractive is false.","commonSituations":"Automated install scripts and CI pipelines forgetting the --provider flag; running install inside a container where TTY detection fails; piping output which disables interactivity.","solutions":["Pass an explicit provider: npx claude-mem install --provider claude (or host/cmem)","Run the installer in an interactive terminal (no pipe/redirect of stdin)","If scripting, supply any other required non-interactive inputs (API keys etc.) alongside --provider"],"exampleFix":"// before\nnpx claude-mem install < /dev/null\n// after\nnpx claude-mem install --provider claude","handlingStrategy":"try-catch","validationCode":"if (!process.argv.includes('--provider') && !process.stdout.isTTY) {\n  throw new Error('Non-interactive install requires --provider');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await runInstall(options);\n} catch (e) {\n  if (e.message === 'Non-interactive provider validation did not run.') {\n    console.error('Pass --provider <claude|host|cmem|...> when running non-interactively.');\n    process.exitCode = 2;\n  } else throw e;\n}","preventionTips":["Always pass --provider in scripts, CI, and any environment with redirected stdin","Check isTTY before invoking the installer, or force a TTY (e.g. script -c)","Keep install commands' non-interactive flags documented in your provisioning scripts"],"tags":["cli","non-interactive","install","missing-flag"],"backgroundTag":"missing-required-flag","analyzedSha":"8bc631a71a487424b866756e43a6efa4574cc66b","analyzedAt":"2026-09-09T10:47:06.009Z","contentChangedAt":"2026-09-09T10:47:06.009Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}