{"record":{"id":"d80b1462822f75f8","repo":"microsoft/aspire","slug":"error","errorCode":null,"errorMessage":"$error","messagePattern":"\\$error","errorType":"exception","errorClass":"AspireError","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.CodeGeneration.Python/PythonModuleBuilder.cs","lineNumber":1150,"sourceCode":"                self,\n                capability_id: str,\n                args: dict[str, typing.Any] | None = None,\n                kwargs: typing.Mapping[str, typing.Any] | None = None\n            ) -> typing.Any:\n                '''\n                Invoke an ATS capability by ID.\n\n                Capabilities are operations exposed by [AspireExport] attributes.\n                Results are automatically wrapped in Handle objects when applicable.\n                '''\n                self._check_connection()\n                result = self._send_request(\"invokeCapability\", capability_id, self._marshal_transport_value(args or {}))\n\n                # Check for structured error response\n                if _is_ats_error(result):\n                    if result[\"$error\"].get(\"code\") == AtsErrorCodes.TYPE_MISMATCH:\n                        raise _format_type_error(result[\"$error\"])\n                    raise AspireError(result[\"$error\"])\n\n                # Wrap handles automatically\n                return _wrap_if_handle(result, self, kwargs)\n\n            def _marshal_transport_value(self, value: typing.Any) -> typing.Any:\n                if callable(value):\n                    return self.register_callback(value)\n                if isinstance(value, dict):\n                    return {key: self._marshal_transport_value(nested_value) for key, nested_value in value.items()}\n                if isinstance(value, (list, tuple)):\n                    return [self._marshal_transport_value(item) for item in value]\n                return value\n\n            def _send_request(self, method: str, *params: typing.Any) -> typing.Any:\n                '''Send a JSON-RPC request and wait for response'''\n                with self._lock:\n                    self._request_id += 1\n                    request_id = self._request_id","sourceCodeStart":1132,"sourceCodeEnd":1168,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.CodeGeneration.Python/PythonModuleBuilder.cs#L1132-L1168","documentation":"invoke_capability() raises AspireError(result['$error']) when the AppHost returns a structured error response for the capability call. The literal '$error' in the message is the response key inspected here; the raised AspireError carries the server-side error code and message. Type-mismatch errors are converted to a formatted type error instead via _format_type_error.","triggerScenarios":"Calling client.invoke_capability(capability_id, args) where the server rejects the call: unknown capability id, invalid/mistyped arguments, or any capability-level failure surfaced through the $error field.","commonSituations":"Typos in capability_id; passing Python values the server cannot unmarshal (wrong types, unsupported fields); calling a capability removed or renamed after an AppHost/SDK update; server-side validation rejecting the argument dict.","solutions":["Read the raised AspireError's code/message to identify the server-side cause.","Verify the capability_id matches one advertised by the AppHost (list capabilities or check generated stubs).","Fix argument types to match the capability schema; use the generated wrapper methods where available.","Regenerate the Python module if the AppHost version changed and capabilities were renamed."],"exampleFix":"// before\nresult = client.invoke_capability(\"add_resoruce\", {\"name\": 123})\n// after\nresult = client.invoke_capability(\"add_resource\", {\"name\": \"cache\"})","handlingStrategy":"try-catch","validationCode":"def assert_capability(client, capability_id, capabilities):\n    if capability_id not in capabilities:\n        raise ValueError(f'unknown capability {capability_id!r}')","typeGuard":null,"tryCatchPattern":"try:\n    result = client.invoke_capability(capability_id, args)\nexcept AspireError as e:\n    log.error('capability %s failed: %s (%s)', capability_id, e.message, getattr(e, 'code', None))\n    raise","preventionTips":["Use generated wrapper methods instead of raw invoke_capability where available","Validate capability ids against the advertised list","Keep argument types aligned with the capability schema; regenerate stubs after AppHost updates"],"tags":["python","rpc","capability","server-error"],"backgroundTag":"api-error-response","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}