{"record":{"id":"30f10a5662631de6","repo":"BoundaryML/baml","slug":"failed-to-get-usage-w-rawobjects-llm-call","errorCode":null,"errorMessage":"failed to get usage: %w","messagePattern":"failed to get usage: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/language_client_go/pkg/rawobjects_llm_call.go","lineNumber":99,"sourceCode":"\t\treturn nil, fmt.Errorf(\"failed to get http response: %w\", err)\n\t}\n\n\tif result == nil {\n\t\treturn nil, nil\n\t}\n\n\tresponse, ok := result.(HTTPResponse)\n\tif !ok {\n\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)","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/language_client_go/pkg/rawobjects_llm_call.go#L81-L117","documentation":"LLMCall.Usage() wraps any error from CallMethod(l, \"usage\", nil) when reading token-usage information from the LLM call. It means the runtime failed to resolve the \"usage\" attribute across the FFI boundary. A genuinely absent usage returns (nil, nil); this error indicates a lookup/dispatch failure, typically a stale object handle or runtime error.","triggerScenarios":"Calling Usage() on an llmCall whose RawObject was freed, or when the runtime errors dispatching the \"usage\" method — e.g. querying usage before the provider response was fully parsed on runtimes that error rather than return null.","commonSituations":"Reading usage mid-stream before the provider reported usage; accessing the object after runtime cleanup; Go binding/native runtime version mismatch.","solutions":["Read Usage() only after the call/stream completes and usage has been reported.","Consume the call object within the scope that produced it, before runtime cleanup.","Match Go binding and native runtime versions, then regenerate bindings.","Treat (nil, nil) as 'usage not available' and only unwrap errors for genuine failures."],"exampleFix":"// before: usage read mid-stream\nusage, err := call.Usage()\n\n// after: after completion\nfinal, err := stream.Finish()\nif err == nil {\n    usage, err := call.Usage()\n    if err != nil || usage == nil {\n        log.Printf(\"usage unavailable: %v\", err)\n    }\n}","handlingStrategy":"try-catch","validationCode":"// Ensure the call completed and usage was reported:\n// if !call.Completed() { return errors.New(\"usage not yet available\") }","typeGuard":null,"tryCatchPattern":"usage, err := call.Usage()\nif err != nil {\n    log.Printf(\"usage unavailable: %v\", err)\n    return\n}\nif usage == nil {\n    // usage legitimately absent (e.g. provider did not report tokens)\n}","preventionTips":["Read usage only after call completion.","Treat nil usage as 'not reported', not an error.","Consume call objects before runtime cleanup.","Match bindings and runtime versions."],"tags":["ffi","runtime","binding","usage","baml"],"backgroundTag":"internal-invariant-violation","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}