{"record":{"id":"a6316933b7b0c2c6","repo":"larksuite/cli","slug":"protocol-unknown-message-type-q","errorCode":null,"errorMessage":"protocol: unknown message type %q","messagePattern":"protocol: unknown message type %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/event/adapter/localbus/protocol/codec.go","lineNumber":116,"sourceCode":"\t\tmsg = &HelloAck{}\n\tcase MsgTypeEvent:\n\t\tmsg = &Event{}\n\tcase MsgTypeBye:\n\t\tmsg = &Bye{}\n\tcase MsgTypePreShutdownCheck:\n\t\tmsg = &PreShutdownCheck{}\n\tcase MsgTypePreShutdownAck:\n\t\tmsg = &PreShutdownAck{}\n\tcase MsgTypeStatusQuery:\n\t\tmsg = &StatusQuery{}\n\tcase MsgTypeStatusResponse:\n\t\tmsg = &StatusResponse{}\n\tcase MsgTypeShutdown:\n\t\tmsg = &Shutdown{}\n\tcase MsgTypeSourceStatus:\n\t\tmsg = &SourceStatus{}\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"protocol: unknown message type %q\", env.Type)\n\t}\n\n\tif err := json.Unmarshal(line, msg); err != nil {\n\t\treturn nil, fmt.Errorf(\"protocol decode %s: %w\", env.Type, err)\n\t}\n\treturn msg, nil\n}\n","sourceCodeStart":98,"sourceCodeEnd":124,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/event/adapter/localbus/protocol/codec.go#L98-L124","documentation":"protocol.Decode parsed the JSON envelope but its 'type' field does not match any known message type constant (Hello, Event, StatusResponse, Shutdown, SourceStatus), so no target struct exists to unmarshal into. This guards the protocol against version skew and garbage-with-valid-JSON frames.","triggerScenarios":"Decode reads a line whose JSON has a 'type' value outside the known set — a peer on a newer/older protocol version, a typo'd type string, or a foreign JSON line reaching the bus stream.","commonSituations":"CLI and long-running bus binary updated to different versions (old bus doesn't know new message types); hand-crafted test/status probes sending wrong type; another process writing unrelated JSON into the same file/socket.","solutions":["Log the %q type value from the error and compare against the sender's protocol constants","Upgrade/downgrade so both bus and client use the same lark-cli version (protocol mismatch is the usual cause)","Fix the sender to use the exported MsgType* constants instead of string literals","If forward-compatibility is needed, have the reader ignore unknown types instead of failing the connection"],"exampleFix":"// before\nconn.Write([]byte(`{\"type\":\"Ping\"}`))\n// after\nprotocol.Encode(conn, &protocol.Hello{}) // uses MsgTypeHello constant","handlingStrategy":"type-guard","validationCode":"func knownType(line []byte) bool {\n\tvar env struct{ Type string `json:\"type\"` }\n\tif json.Unmarshal(line, &env) != nil {\n\t\treturn false\n\t}\n\tswitch env.Type {\n\tcase protocol.MsgTypeHello, protocol.MsgTypeEvent,\n\t\tprotocol.MsgTypeStatusResponse, protocol.MsgTypeShutdown,\n\t\tprotocol.MsgTypeSourceStatus:\n\t\treturn true\n\t}\n\treturn false\n}","typeGuard":"func isUnknownTypeError(err error) bool {\n\treturn err != nil && strings.HasPrefix(err.Error(), \"protocol: unknown message type\")\n}","tryCatchPattern":"msg, err := protocol.Decode(line)\nif err != nil {\n\tif isUnknownTypeError(err) {\n\t\tlog.Printf(\"ignoring unknown message from peer: %v\", err)\n\t\treturn nil // skip frame; keep connection alive\n\t}\n\treturn err\n}","preventionTips":["Always build messages with the exported MsgType* constants, never inline strings","Pin CLI and bus process to the same release; restart the bus after upgrades","When adding a message type, update both encoder and decoder switch in the same PR","Log-and-skip unknown types at protocol boundaries to tolerate forward-compatible peers"],"tags":["go","localbus-protocol","version-skew","unknown-type"],"backgroundTag":"unknown-message-type","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}