{"record":{"id":"4e1f699429093909","repo":"t8y2/dbx","slug":"agentsessionid-is-required-4e1f69","errorCode":null,"errorMessage":"agentSessionId is required","messagePattern":"agentSessionId is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/etcd-go/main.go","lineNumber":205,"sourceCode":"\t}\n\tif len(req.ID) == 0 {\n\t\treq.ID = json.RawMessage(\"1\")\n\t}\n\tresult, shutdown, err := r.dispatch(req.Method, req.Params)\n\tif err != nil {\n\t\treturn errorResponse(req.ID, req.Method, stringParam(req.Params, \"agentSessionId\"), err), false\n\t}\n\treturn response{JSONRPC: \"2.0\", ID: req.ID, Result: result}, shutdown\n}\n\nfunc (r *runtimeServer) dispatch(method string, params map[string]json.RawMessage) (any, bool, error) {\n\tswitch method {\n\tcase \"handshake\":\n\t\treturn handshakeResult(), false, nil\n\tcase \"open_session\":\n\t\tid := requiredSessionID(params)\n\t\tif id == \"\" {\n\t\t\treturn nil, false, errors.New(\"agentSessionId is required\")\n\t\t}\n\t\treturn r.openSession(id, params)\n\tcase \"close_session\":\n\t\treturn r.closeSession(stringParam(params, \"agentSessionId\")), false, nil\n\tcase \"validate_session\":\n\t\tsession, err := r.session(requiredSessionID(params))\n\t\tif err != nil {\n\t\t\treturn nil, false, err\n\t\t}\n\t\tsession.mu.Lock()\n\t\tdefer session.mu.Unlock()\n\t\tresult, err := session.state.validateConnection()\n\t\treturn result, false, err\n\tcase \"cancel_session\":\n\t\tsession, err := r.session(requiredSessionID(params))\n\t\tif err != nil {\n\t\t\treturn nil, false, err\n\t\t}","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/etcd-go/main.go#L187-L223","documentation":"The dispatcher (dispatch in main.go) routes the open_session method; it requires a non-empty agentSessionId. requiredSessionID extracts the value, and if the resulting string is empty, dispatch returns \"agentSessionId is required\" before r.openSession is ever called. It is a session-lifecycle protocol validation error.","triggerScenarios":"Sending an open_session request whose params omit agentSessionId, or contain an empty string (\"\") — detected at main.go:205 in the dispatch switch.","commonSituations":"Client SDK misconfiguration where the session ID is generated lazily and not set before open_session; JSON params using the wrong field name; templates/tests that build open_session payloads without the ID.","solutions":["Always include a non-empty \"agentSessionId\" string in open_session params.","Generate the session ID client-side (UUID/ULID) before dispatching open_session.","Fix param-building code so the field name matches \"agentSessionId\" exactly (case-sensitive)."],"exampleFix":"// before\n{\"method\": \"open_session\", \"params\": {}}\n\n// after\n{\"method\": \"open_session\", \"params\": {\"agentSessionId\": \"6f1c...\"}}","handlingStrategy":"validation","validationCode":"if sessionID == \"\" {\n    return errors.New(\"cannot open_session: agentSessionId is empty; generate a UUID first\")\n}","typeGuard":"func validSessionID(v any) (string, bool) {\n    s, ok := v.(string)\n    return s, ok && s != \"\"\n}","tryCatchPattern":null,"preventionTips":["Generate the session ID (UUID/ULID) before dispatching open_session.","Match the exact field name 'agentSessionId' (camelCase).","Add a constructor for session params so the ID can't be omitted."],"tags":["etcd","session","validation","missing-parameter"],"backgroundTag":"missing-required-parameter","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}