{"record":{"id":"e7617bef37b38113","repo":"chenhg5/cc-connect","slug":"wps-agentspace-parse-message-w","errorCode":null,"errorMessage":"wps-agentspace: parse message: %w","messagePattern":"wps-agentspace: parse message: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"platform/wps-agentspace/wpsagentspace.go","lineNumber":525,"sourceCode":"\t\t\t\t\"USER_NO_APP_PERMISSION\",\n\t\t\t\t\"USER_NO_OPENCLAW_PERMISSION\",\n\t\t\t\t\"OPENCLAW_NOT_CONFIGURED\",\n\t\t\t\t\"NOT_OPENCLAW_APP\",\n\t\t\t\t\"NOT_LOGIN\",\n\t\t\t}\n\t\t\tfor _, code := range fatalCodes {\n\t\t\t\tif data.Code == code {\n\t\t\t\t\treturn fmt.Errorf(\"wps-agentspace: fatal error: %s\", data.Code)\n\t\t\t\t}\n\t\t\t}\n\t\t\tslog.Warn(\"wps-agentspace: server error\", \"code\", data.Code)\n\t\t}\n\t\treturn nil\n\n\tcase \"message\":\n\t\tvar data messageData\n\t\tif err := json.Unmarshal(frame.Data, &data); err != nil {\n\t\t\treturn fmt.Errorf(\"wps-agentspace: parse message: %w\", err)\n\t\t}\n\t\tslog.Debug(\"wps-agentspace: message frame\", \"role\", data.Role, \"type\", data.Type, \"content_len\", len(data.Content))\n\t\tif data.Role == \"user\" {\n\t\t\treturn p.handleUserMessage(data)\n\t\t}\n\t\treturn nil\n\n\tdefault:\n\t\treturn nil\n\t}\n}\n\n// handleUserMessage processes an incoming user message.\nfunc (p *Platform) handleUserMessage(data messageData) error {\n\tchatID := data.SessionID\n\tif chatID == \"\" {\n\t\tchatID = data.ChatID\n\t}","sourceCodeStart":507,"sourceCodeEnd":543,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/wps-agentspace/wpsagentspace.go#L507-L543","documentation":"If the JSON payload of an incoming \"message\" frame cannot be unmarshaled into messageData, handleFrame returns \"wps-agentspace: parse message: %w\". readLoop logs it via slog.Error and continues the loop, so this does not kill the connection — the offending frame is simply dropped. It indicates the server sent a message body that does not match the client's expected schema.","triggerScenarios":"event=\"message\" whose frame.data is malformed JSON or whose field types differ from messageData (e.g. content as an object instead of string, timestamp as string instead of int64) — usually after a server-side API schema change or version mismatch.","commonSituations":"WPS AgentSpace rolling out a new message format that an older cc-connect build does not know; a corrupt/proxied frame; testing against a mock or newer dev endpoint emitting different messageData shapes.","solutions":["Check the wrapped unmarshal error to see which field/type mismatched","Upgrade cc-connect to a version matching the current AgentSpace v7 message schema","Compare the raw frame (visible in the debug log line \"received frame\") against the messageData struct and adjust the struct tags if you build from source","If caused by a proxy/test mock, fix the frame producer to emit the documented schema"],"exampleFix":"// before\ntype messageData struct {\n\tTimestamp int64  `json:\"timestamp\"`\n\tContent   string `json:\"content\"`\n}\n// after — tolerate a server that sends timestamp as string\nfunc (d *messageData) UnmarshalJSON(b []byte) error {\n\ttype alias messageData\n\tvar raw struct {\n\t\talias\n\t\tTimestamp any `json:\"timestamp\"`\n\t}\n\tif err := json.Unmarshal(b, &raw); err != nil {\n\t\treturn err\n\t}\n\t*d = messageData(raw.alias)\n\tswitch v := raw.Timestamp.(type) {\n\tcase float64:\n\t\td.Timestamp = int64(v)\n\tcase string:\n\t\td.Timestamp, _ = strconv.ParseInt(v, 10, 64)\n\t}\n\treturn nil\n}","handlingStrategy":"type-guard","validationCode":"var probe struct {\n\tEvent string          `json:\"event\"`\n\tData  json.RawMessage `json:\"data\"`\n}\nif err := json.Unmarshal(raw, &probe); err != nil {\n\t// skip frame before handling\n}","typeGuard":"func validMessageFrame(data json.RawMessage) bool {\n\tvar m map[string]any\n\tif json.Unmarshal(data, &m) != nil {\n\t\treturn false\n\t}\n\t_, ok := m[\"content\"].(string)\n\treturn ok\n}","tryCatchPattern":"if err := json.Unmarshal(frame.Data, &data); err != nil {\n\tslog.Warn(\"wps-agentspace: skipping malformed message frame\", \"error\", err)\n\treturn nil // log and continue, don't kill the loop\n}","preventionTips":["Keep cc-connect updated with AgentSpace API schema changes","Log raw frames at debug level to diagnose schema drift quickly","Use json.RawMessage + tolerant decoding for fields prone to type changes","Pin the documented schema in integration tests to catch drift early"],"tags":["json","schema","parsing"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}