{"record":{"id":"fcd1a8cd7db46a96","repo":"sipeed/picoclaw","slug":"turn-s-is-still-active-for-session-q","errorCode":null,"errorMessage":"turn %s is still active for session %q","messagePattern":"turn (.+?) is still active for session %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/agent/steering.go","lineNumber":382,"sourceCode":"\n// Continue resumes an idle agent by dequeuing any pending steering messages\n// and running them through the agent loop. This is used when the agent's last\n// message was from the assistant (i.e., it has stopped processing) and the\n// user has since enqueued steering messages.\n//\n// If no steering messages are pending, it returns an empty string.\nfunc (al *AgentLoop) Continue(ctx context.Context, sessionKey, channel, chatID string) (string, error) {\n\t// Claim the session with a unique placeholder to prevent a TOCTOU race where two\n\t// concurrent Continue calls for the same session both pass the active-turn\n\t// check and create parallel turns. The placeholder is replaced by the real\n\t// turnState inside continueWithSteeringMessages → runAgentLoop → registerActiveTurn.\n\tplaceholder := &turnState{\n\t\tturnID: \"pending-continue-\" + sessionKey + \"-\" + fmt.Sprintf(\"%d\", al.turnSeq.Add(1)),\n\t\tphase:  TurnPhaseSetup,\n\t}\n\tif _, loaded := al.activeTurnStates.LoadOrStore(sessionKey, placeholder); loaded {\n\t\tif active := al.GetActiveTurnBySession(sessionKey); active != nil {\n\t\t\treturn \"\", fmt.Errorf(\"turn %s is still active for session %q\", active.TurnID, sessionKey)\n\t\t}\n\t\t// Another Continue just claimed the slot; let it handle the steering.\n\t\treturn \"\", nil\n\t}\n\n\tif err := al.ensureHooksInitialized(ctx); err != nil {\n\t\tal.activeTurnStates.Delete(sessionKey)\n\t\treturn \"\", err\n\t}\n\tif err := al.ensureMCPInitialized(ctx); err != nil {\n\t\tal.activeTurnStates.Delete(sessionKey)\n\t\treturn \"\", err\n\t}\n\n\tsteeringMsgs := al.dequeueSteeringMessagesForScopeWithFallback(sessionKey)\n\tif len(steeringMsgs) == 0 {\n\t\tal.activeTurnStates.Delete(sessionKey)\n\t\treturn \"\", nil","sourceCodeStart":364,"sourceCodeEnd":400,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/pkg/agent/steering.go#L364-L400","documentation":"Error \"turn %s is still active for session %q\" thrown in sipeed/picoclaw.","triggerScenarios":"Thrown at pkg/agent/steering.go:382 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":[],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}