{"record":{"id":"aa75e2560af7e5a6","repo":"BoundaryML/baml","slug":"unexpected-type-for-usage-t-rawobjects-llm-call","errorCode":null,"errorMessage":"unexpected type for usage: %T","messagePattern":"unexpected type for usage: %T","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/language_client_go/pkg/rawobjects_llm_call.go","lineNumber":108,"sourceCode":"\t\treturn nil, fmt.Errorf(\"unexpected type for http response: %T\", result)\n\t}\n\n\treturn response, nil\n}\n\nfunc (l *llmCall) Usage() (Usage, error) {\n\tresult, err := raw_objects.CallMethod(l, \"usage\", nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get usage: %w\", err)\n\t}\n\n\tif result == nil {\n\t\treturn nil, nil\n\t}\n\n\tusage, ok := result.(Usage)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"unexpected type for usage: %T\", result)\n\t}\n\n\treturn usage, nil\n}\n\nfunc (l *llmCall) Selected() (bool, error) {\n\tresult, err := raw_objects.CallMethod(l, \"selected\", nil)\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"failed to get selected: %w\", err)\n\t}\n\n\tselected, ok := result.(bool)\n\tif !ok {\n\t\treturn false, fmt.Errorf(\"unexpected type for selected: %T\", result)\n\t}\n\n\treturn selected, nil\n}","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/language_client_go/pkg/rawobjects_llm_call.go#L90-L126","documentation":"LLMCall.Usage() asserts the runtime result implements the Usage interface; this error fires when the deserialized FFI value is a different type (%T shows it). It means the runtime returned a present-but-unexpected payload for the usage attribute — a Go-binding/runtime contract mismatch. Nil results are handled earlier and return (nil, nil).","triggerScenarios":"raw_objects.CallMethod(l, \"usage\", nil) returns a non-nil value failing the usage.(Usage) assertion at rawobjects_llm_call.go:106-109 — e.g. a raw CFFI wrapper or an unrelated BAML object type.","commonSituations":"Version skew between Go bindings and native runtime changing the usage encoding; a runtime bug returning a wrapped value instead of the Usage object; objects from mismatched runtime instances.","solutions":["Upgrade the Go bindings and BAML runtime to matching versions and regenerate.","Note the actual type from %T and report the mismatch if it persists across versions.","Degrade gracefully in metrics/tracing code: log and skip usage rather than failing.","Verify the object is an LLM call from the same runtime instance you are querying."],"exampleFix":"// before\nusage, err := call.Usage()\nif err != nil { return err }\nrecord(usage)\n\n// after\nusage, err := call.Usage()\nif err != nil {\n    log.Printf(\"usage type mismatch: %v\", err)\n    return nil\n}\nrecord(usage)","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func isUsage(v interface{}) (baml.Usage, bool) {\n    u, ok := v.(baml.Usage)\n    return u, ok\n}","tryCatchPattern":"usage, err := call.Usage()\nif err != nil {\n    log.Printf(\"usage type mismatch: %v\", err)\n    return nil\n}","preventionTips":["Regenerate bindings after every runtime upgrade.","Log %T on mismatch to pinpoint contract drift.","Wrap usage reads in tolerant error handling for metrics code.","Ensure objects come from the same runtime instance."],"tags":["type-assertion","ffi","binding","usage","baml"],"backgroundTag":"type-mismatch","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}