{"record":{"id":"a26fc027e566ff5d","repo":"charmbracelet/crush","slug":"agent-configuration-is-missing","errorCode":null,"errorMessage":"agent configuration is missing","messagePattern":"agent configuration is missing","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/app/app.go","lineNumber":442,"sourceCode":"\t\t\t\t}\n\t\t\t\t// Ignore initial whitespace-only messages.\n\t\t\t\tif printed || strings.TrimSpace(part) != \"\" {\n\t\t\t\t\tprinted = true\n\t\t\t\t\tfmt.Fprint(output, part)\n\t\t\t\t}\n\t\t\t\tmessageReadBytes[msg.ID] = len(content)\n\t\t\t}\n\n\t\tcase <-ctx.Done():\n\t\t\tstopSpinner()\n\t\t\treturn ctx.Err()\n\t\t}\n\t}\n}\n\nfunc (app *App) UpdateAgentModel(ctx context.Context) error {\n\tif app.AgentCoordinator == nil {\n\t\treturn fmt.Errorf(\"agent configuration is missing\")\n\t}\n\treturn app.AgentCoordinator.UpdateModels(ctx)\n}\n\n// restoreModelFromSession reads the last assistant message in the\n// session and, if it used a different provider/model than the current\n// config, overrides the preferred model in-memory (non-persistent)\n// provided the provider/model is still available. This ensures that\n// continuing a session uses the same model that produced the last\n// response.\nfunc (app *App) restoreModelFromSession(ctx context.Context, sessionID string) error {\n\tlastMsg, err := app.Messages.GetLastAssistantMessage(ctx, sessionID)\n\tif err != nil {\n\t\tif errors.Is(err, sql.ErrNoRows) {\n\t\t\treturn nil\n\t\t}\n\t\treturn fmt.Errorf(\"failed to get last assistant message: %w\", err)\n\t}","sourceCodeStart":424,"sourceCodeEnd":460,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/app/app.go#L424-L460","documentation":"UpdateAgentModel requires app.AgentCoordinator to be non-nil before delegating to UpdateModels. If the App was constructed without an agent coordinator (initialization skipped or failed earlier, or UpdateAgentModel called on a partially-initialized App), this sentinel error is returned.","triggerScenarios":"Calling app.UpdateAgentModel(ctx) on an App whose AgentCoordinator was never initialized — e.g. before InitCoderAgent/agent wiring completed, or after initialization failed and the error was ignored.","commonSituations":"Embedding crush as a library and calling UpdateAgentModel before app setup finished; initialization error swallowed earlier in startup; tests constructing App directly without a coordinator.","solutions":["Ensure App initialization (agent coordinator wiring) completes before calling UpdateAgentModel","Check and handle errors from earlier init steps instead of ignoring them","Nil-check/validate the App in your integration code before invoking agent methods"],"exampleFix":"// before\napp.UpdateAgentModel(ctx) // may panic/error if coordinator missing\n// after\nif app.AgentCoordinator == nil {\n\tif err := app.InitCoderAgent(ctx); err != nil {\n\t\treturn err\n\t}\n}\nif err := app.UpdateAgentModel(ctx); err != nil {\n\treturn err\n}","handlingStrategy":"type-guard","validationCode":"if app == nil || app.AgentCoordinator == nil {\n\treturn errors.New(\"app not fully initialized; run InitCoderAgent first\")\n}","typeGuard":"func agentReady(app *app.App) bool {\n\treturn app != nil && app.AgentCoordinator != nil\n}","tryCatchPattern":"if err := app.UpdateAgentModel(ctx); err != nil {\n\tif err.Error() == \"agent configuration is missing\" {\n\t\treturn fmt.Errorf(\"call Init/InitCoderAgent before UpdateAgentModel: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Always complete App initialization before calling agent methods","Handle init errors from earlier startup steps instead of ignoring them","In tests, construct App via the real constructor that wires the coordinator"],"tags":["go","nil-check","initialization","agent-coordinator"],"backgroundTag":"nil-dependency","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}