Known limitations

This page describes the current limitations of Graftcode for external developers. Graftcode is in Alpha: many paths work end to end, but support is directional and pair-specific. A runtime name in Gateway, a method in the callable surface, or a generated package by itself does not mean the complete Receiver-to-Caller path works. Validate the exact runtime pair, generated package, transport, and deployment you intend to operate.

Statuses used on this page:

  • Available — supported in the current release.
  • Alpha — usable but not hardened; expect gaps and validate before depending on it.
  • Preview — early, incomplete, or plugin-based; not guaranteed.
  • Planned — not available yet.
  • Unsupported — not supported; do not depend on it.

Where support depends on the runtime pair, that is stated directly (for example, Available for .NET and Node.js; other pairs require validation).

Contracts and types

CapabilityStatusCurrent limitationRecommended approach
Primitive and string contractsAvailablePrefer primitives, strings, arrays of supported values, and plain models.
Framework complex types on the public surface (for example DateTime)UnsupportedPackage generation rejects them ("complex types from framework in public interfaces is not supported").Use ISO-8601 strings for dates and string identifiers; model your own plain types.
Rich shapes (nested models, nullability, enums, unions, maps, sets)Available for .NET and Node.js; other pairs require validationBehavior differs across runtimes; unknown values can degrade.Generate and smoke-test every target package; keep contracts simple.
GenericsAvailable for .NET; other pairs require validationConstraints, variance, overloads, and nested generics are not portable across all pairs.Expose a concrete facade with closed, simple types; keep generics behind it.
Inheritance and polymorphismRequires validationConstructor, member, dispatch, and serialization semantics are not portable for arbitrary hierarchies.Flatten the public contract into standalone facade types; delegate internally.
64-bit integers and decimal to a JavaScript CallerRequires validationJavaScript number cannot safely represent every 64-bit or exact-decimal value.Use int or a string for exact values unless the exact pair is tested.

See Type compatibility matrix and Type mapping.

Runtime support

CapabilityStatusCurrent limitationRecommended approach
.NET, Node.js/TypeScript, Java/JVM, Python 3, PHP, RubyAvailableSupport is directional; one direction working does not prove the reverse.Test each Receiver-to-Caller direction the application uses.
Perl as a Receiver that produces a GraftUnsupportedGateway can host Perl code, but there is no Graft-generation path for a Perl Receiver.Do not plan to publish a Graft from a Perl Receiver.
Specific framework/interpreter versionsAvailable for documented versionsNot every patch version, distribution, target framework, or JVM language is guaranteed.Match the version the Gateway release documents, then smoke-test in the target environment.

See Supported runtimes and package managers.

Invocation and async

CapabilityStatusCurrent limitationRecommended approach
Async on a .NET Receiver's public methodUnsupportedTask/Task<T> and cancellation tokens are not accepted on the public surface.Keep public methods synchronous; use async internally.
Asynchronous generated Caller APIAvailable for Node.js/TypeScriptThe generated call may return a Promise<T> even when the Receiver method is synchronous.Follow the exact call shape in the installed package and Vision.
Cross-runtime cancellation and timeoutsUnsupported (built-in)There is no built-in cross-runtime cancellation.Apply timeouts, retries, and cancellation in Caller code and infrastructure.
Callbacks, delegates, and eventsPreviewLifecycle, reconnect, error, and browser behavior are not established across pairs.Use request/result methods; add callbacks only after an end-to-end test for the exact pair and transport.

See Async, cancellation, and timeouts.

Stateful behavior

CapabilityStatusCurrent limitationRecommended approach
Static (stateless) operationsAvailableA static facade is not automatically stateless if it holds shared state.Prefer static input-to-output operations; keep them free of shared mutable state.
Instance / remote object referencesAlphaNo durable lifetime guarantee across reconnects, retries, Gateway restarts, transports, or pairs.Keep durable state behind explicit IDs rather than persisting remote object references.

See Static and instance context.

Package generation and registry

CapabilityStatusCurrent limitationRecommended approach
Registry coordinates and install commandsAvailableNames, versions, registry paths, namespaces, and imports depend on the active Gateway/project; a restart without a stable Project Key can change the registry identity.Copy the complete command and generated import from the running Gateway/Vision; never reuse example coordinates.
npm runtime dependencyAvailableGenerated npm packages depend on a runtime SDK; automatic resolution is package-specific.Run the exact npm command emitted for the Graft, keep the lockfile, and inspect installed metadata if resolution fails.
OS / architecture coverageRequires validationNative and plugin paths are OS/architecture specific; there is no exhaustive release matrix.Build and smoke-test on the deployment OS/architecture; verify executable permissions and native assets.

Transports

CapabilityStatusCurrent limitationRecommended approach
In-memory and WebSocket (ws://, wss://)AvailableUse wss:// for network calls; copy the exact host and path from Vision.
TCP and HTTP/2 listenersAvailable (opt-in)Require their enabling options; do not have identical failure/header semantics.Enable the listener explicitly and verify the route through your proxy/ingress.
Message-queue / broker transportsPreview (plugin-based)Availability depends on a specific transport plugin; not built in.Do not assume a broker is supported because it appears in a diagram; verify the plugin.
Proxy, ingress, certificate, keepalive behaviorRequires validationDeployment-specific.Terminate TLS with a configuration tested for that deployment.

See Ports and protocols.

Security

CapabilityStatusCurrent limitationRecommended approach
Invocation authentication and authorizationAlphaNot automatic; if nothing is configured, no invocation authentication occurs. The Project Key is not runtime-call authorization.Pass and validate credentials before business effects; test rejection as well as success. See Authentication and authorization.
Browser custom headers on the WebSocket handshakeUnsupportedBrowser WebSocket handshakes cannot set arbitrary custom headers.Pass credentials as a supported method parameter, or use the HTTP/2 configuration emitted by Vision.

Observability

CapabilityStatusCurrent limitationRecommended approach
W3C Trace Context propagationAvailable for .NET and Node.js; other runtimes require validationNo guarantee of automatic end-to-end traces on every runtime/transport.Instrument Caller and Receiver with OpenTelemetry; verify parent/child spans in a smoke test. See Observability.
Built-in metrics / log collectorUnsupportedGateway does not provide a built-in collector.Export telemetry with your own OpenTelemetry/logging stack.

Configuration

CapabilityStatusCurrent limitationRecommended approach
Six-level configuration precedenceAvailable for .NET and Node.jsRuntime context is cached after first initialization; at equal name and priority, first registration wins.Set configuration before the first generated call; inspect higher-priority sources when a setting seems ignored. See Configuration resolution.

Operations

CapabilityStatusCurrent limitationRecommended approach
Liveness endpointAvailableGateway provides GET /status for liveness only.Use /status for liveness; implement readiness/dependency checks yourself.
Readiness / dependency healthApplication-definedNo built-in readiness or dependency-health endpoint.Add readiness and dependency checks at an owned layer.
Retry, backoff, failover, idempotency, exactly-onceUnsupported (built-in)Retrying an invocation can repeat business effects.Add resilience at an owned layer; retry only operations designed and tested as idempotent; use explicit operation IDs for deduplication.
Ports and runtime detectionAvailableDefault ports can be occupied or require privileges; auto-detection can select the wrong module/runtime.Provide the exact module and runtime and use available ports; confirm discovery and publication before installing a Graft.

Vision

CapabilityStatusCurrent limitationRecommended approach
Browse callable surface, package coordinates, install command, configuration, versionAvailableReflects only the modules loaded by that Gateway process.Use Vision as the source for install and configuration details for the running Gateway. See Graftcode Vision.

MCP

CapabilityStatusCurrent limitationRecommended approach
Expose a callable surface over MCPAvailableScope depends on the runtime and configuration.Follow the MCP Quick Start for the end-to-end flow; see Expose methods over MCP.

Compatibility

CapabilityStatusCurrent limitationRecommended approach
Backward compatibility across releasesVersion-dependentNo universal wire, binary, source, or old-Caller/new-Receiver guarantee. Additive source changes can still change generated names, overloads, exports, or mappings.Pin all participating versions, regenerate deliberately, compare the generated public API, then compile and smoke-test representative Callers before rollout. See Contract evolution.
Production readinessAlphaSupport for advanced types, all pairs, security distribution, upgrades, HA, and every platform is incomplete.Define and test a narrow supported profile (exact versions, simple contract, locked packages, TLS/auth, timeouts, failure handling, restart, rollback, upgrade).

Runtime-specific notes

.NET

  • SDK-style projects compile all .cs files recursively. Keep Caller and test projects outside the Receiver library directory so unintended code does not enter the callable surface.
  • Public methods must be synchronous; a public async/Task<T> is not a portable contract.

Node.js / TypeScript

  • Build TypeScript first and ensure package metadata resolves to the emitted JavaScript.
  • In stateless mode, await the top-level generated call rather than each returned accessor.
  • Browser bundlers may need polyfills for Node built-ins used by the generated package.
  • Framework route handlers and server actions are adapters, not the callable surface.

Java / JVM

  • Expose Kotlin companion methods as JVM-static (@JvmStatic) so they appear as static operations.
  • Keep custom exception types package-private so they do not enter the callable surface.

Python

  • Importing the module can run module initialization code. Keep Receiver imports deterministic and free of unsafe startup side effects.
  • Distribution names and import paths often differ; use the exact import shown in Vision.

Ruby

  • The package name and require name can use different normalization; use the emitted require name.
  • Prefer current Gateway output for generated module paths.

PHP

  • Composer packages may run post-install steps; retain the generated package scripts.
  • Verify the generated autoload path rather than relying on autoloading alone in older packages.

See Supported runtimes and package managers and the Type compatibility matrix for role support and type behavior.

Next steps

  1. Select the exact runtime direction in Supported runtimes and package managers.
  2. Reduce the public contract using Callable surface and Type mapping.
  3. Publish once, copy package coordinates from the running Gateway/Vision, and run local and remote smoke tests.
  4. Use the Troubleshooting index for symptom-based diagnostics.