{"record":{"id":"3714e1a37541926c","repo":"wavetermdev/waveterm","slug":"widget-id-must-be-8-characters","errorCode":null,"errorMessage":"widget_id must be 8 characters","messagePattern":"widget_id must be 8 characters","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wcore/wcore.go","lineNumber":131,"sourceCode":"\tif err != nil {\n\t\tlog.Printf(\"error getting object for update event: %v\", err)\n\t\treturn\n\t}\n\twps.Broker.Publish(wps.WaveEvent{\n\t\tEvent:  wps.Event_WaveObjUpdate,\n\t\tScopes: []string{oref.String()},\n\t\tData: waveobj.WaveObjUpdate{\n\t\t\tUpdateType: waveobj.UpdateType_Update,\n\t\t\tOType:      waveObj.GetOType(),\n\t\t\tOID:        waveobj.GetOID(waveObj),\n\t\t\tObj:        waveObj,\n\t\t},\n\t})\n}\n\nfunc ResolveBlockIdFromPrefix(ctx context.Context, tabId string, blockIdPrefix string) (string, error) {\n\tif len(blockIdPrefix) != 8 {\n\t\treturn \"\", fmt.Errorf(\"widget_id must be 8 characters\")\n\t}\n\n\ttab, err := wstore.DBMustGet[*waveobj.Tab](ctx, tabId)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error getting tab: %w\", err)\n\t}\n\n\tfor _, blockId := range tab.BlockIds {\n\t\tif strings.HasPrefix(blockId, blockIdPrefix) {\n\t\t\treturn blockId, nil\n\t\t}\n\t}\n\n\treturn \"\", fmt.Errorf(\"widget_id not found: %q\", blockIdPrefix)\n}\n\nfunc GoSendNoTelemetryUpdate(telemetryEnabled bool) {\n\tgo func() {","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wcore/wcore.go#L113-L149","documentation":"ResolveBlockIdFromPrefix resolves an 8-character block/widget id prefix to a full block id within a tab. It strictly validates the prefix length up front and rejects anything that is not exactly 8 characters with this literal message (the wording says widget_id but it applies to the blockIdPrefix argument).","triggerScenarios":"Calling ResolveBlockIdFromPrefix (directly or via CreateToolUseData, getTermScrollbackOutput, or AI tool-use handlers) with a blockIdPrefix whose len() != 8 — e.g. a full 36-char UUID, an empty string, or a truncated prefix of the wrong length.","commonSituations":"AI/tool integrations passing a full UUID block id instead of the 8-char prefix; frontends sending user-truncated text of arbitrary length; copy/paste errors in tool call arguments.","solutions":["Pass exactly the first 8 characters of the block id","Trim/validate the prefix before calling: strings.TrimSpace and len check","If you have a full UUID, slice it: id[:8]","Check the caller's serialization — some paths may pass an empty string"],"exampleFix":"// before\nblockId, err := wcore.ResolveBlockIdFromPrefix(ctx, tabId, fullBlockUUID)\n// after\nif len(fullBlockUUID) >= 8 {\n    blockId, err = wcore.ResolveBlockIdFromPrefix(ctx, tabId, fullBlockUUID[:8])\n}","handlingStrategy":"validation","validationCode":"if len(strings.TrimSpace(blockIdPrefix)) != 8 {\n    return fmt.Errorf(\"prefix must be exactly 8 chars, got %d\", len(blockIdPrefix))\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always slice full UUIDs to id[:8] before resolving","Trim user/tool-provided input","Validate prefix length at the tool-call boundary","Document the 8-char prefix contract in tool schemas"],"tags":["validation","input","block-id"],"backgroundTag":"invalid-argument-length","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}