Skip to content

Surface plugin mutation errors - #12

Merged
gabek merged 2 commits into
mainfrom
gek/plugin-action-errors
Aug 3, 2026
Merged

Surface plugin mutation errors#12
gabek merged 2 commits into
mainfrom
gek/plugin-action-errors

Conversation

@gabek

@gabek gabek commented Aug 3, 2026

Copy link
Copy Markdown
Member

Mutation calls now throw when Owncast rejects them instead of failing silently.

  • Decode the {error?} result from runtime actions, KV writes, chat moderation, and user moderation in both SDKs
  • Update the JavaScript and Python engine import declarations for the new return values
  • Keep the host runtime, test mocks, wire protocol, examples, and author guidance in sync
  • Pin the host runtime to the matching Owncast commit

Before:

owncast.actions.add({ title: "broken" })
returns without reporting the rejected action

After:

Error: actions[0]: exactly one of url or html is required

I ran the host-runtime Go tests, checked the JavaScript and Python sources, and built both shared engines and action-button examples against the matching runtime.

Requires owncast/owncast#5106.

Copilot AI review requested due to automatic review settings August 3, 2026 20:19

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the Owncast plugin SDKs (JavaScript + Python) and host runtime contract so that mutation-style host calls decode the runtime { error? } result and throw when Owncast rejects an operation, instead of failing silently. It also aligns engine import declarations, mocks, docs, and examples with the new “operation result” return values.

Changes:

  • Decode and surface { error? } results for chat moderation, user moderation, KV writes, and runtime action-button mutations in both SDKs.
  • Update the shared engine import/type declarations to reflect host functions that now return a result pointer instead of void.
  • Synchronize host-runtime mocks/dev-server hooks, wire protocol docs, author guide, examples, and pin the host-runtime Owncast dependency to the matching commit.

Reviewed changes

Copilot reviewed 11 out of 14 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
sdks/python/owncast_plugin/init.py Wrap mutation calls with _operation_result(...) and raise on host-returned errors.
sdks/js/index.js Require and validate operation-result payloads for mutation calls; update actions add/clear to use operation results.
sdks/js/index.d.ts Document that mutation APIs now throw when the host rejects operations.
host-runtime/plugin/testing/mocks.go Update mock HostEnv hooks to return error for mutation hooks.
host-runtime/main.go Update demo HostEnv hooks to return error for user moderation hooks.
host-runtime/go.sum Pin github.com/owncast/owncast to a newer pseudo-version matching required behavior.
host-runtime/go.mod Bump Owncast dependency version to the matching commit.
host-runtime/cmd/owncast-plugin-serve/main.go Update dev server HostEnv mutation hooks to return error.
examples/python/action-buttons/README.md Document that action mutations raise and reject the whole batch on failure.
examples/js/action-buttons/README.md Document that action mutations throw and reject the whole batch on failure.
engines/javascript/engine.d.ts Update host import signatures to return PTR for operation-result-returning functions.
engines/build_py.py Update generated Python host import declarations to include return values for operation-result host calls.
docs/WIRE_PROTOCOL.md Update the wire contract to specify JSON {error?: string}-style outputs for mutations.
docs/PLUGIN_AUTHOR_GUIDE.md Document throwing semantics and batch rejection behavior for action mutations.
Suppressed comments (7)

sdks/python/owncast_plugin/init.py:449

  • The error check uses result.get("error"), which will silently treat an empty-string error as success. Prefer checking for the presence of the error key and keep a fallback message.
        if result.get("error"):
            raise RuntimeError(result["error"])

sdks/python/owncast_plugin/init.py:462

  • The error check uses result.get("error"), which will silently treat an empty-string error as success. Prefer checking for the presence of the error key (consistent with the SQL/video_config wrappers).
        if result.get("error"):
            raise RuntimeError(result["error"])

sdks/python/owncast_plugin/init.py:642

  • The error check uses result.get("error"), which can miss failures if the host returns an empty-string error. Check for the key and include a fallback message.
        if result.get("error"):
            raise RuntimeError(result["error"])

sdks/python/owncast_plugin/init.py:649

  • The error check uses result.get("error"), which can miss failures if the host returns an empty-string error. Check for the key and include a fallback message.
        if result.get("error"):
            raise RuntimeError(result["error"])

sdks/python/owncast_plugin/init.py:729

  • The error check uses result.get("error"), which can miss failures if the host returns an empty-string error. Check for the key and include a fallback message.
        if result.get("error"):
            raise RuntimeError(result["error"])

sdks/python/owncast_plugin/init.py:736

  • The error check uses result.get("error"), which can miss failures if the host returns an empty-string error. Check for the key and include a fallback message.
        if result.get("error"):
            raise RuntimeError(result["error"])

sdks/js/index.js:882

  • Same as add(...): clear() now uses hostFns(...), which loses the more actionable permError(...) guidance for authors who forget ui.modify in the manifest. Restoring the explicit check also avoids leaving permError unused.
      const fns = hostFns("owncast_clear_actions", Permissions.UIModify);
      requireOperationResult(
        fns.owncast_clear_actions(),
        "owncast.actions.clear failed",
      );

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread sdks/python/owncast_plugin/__init__.py Outdated
Comment thread sdks/js/index.js
@gabek
gabek merged commit 55cd4ec into main Aug 3, 2026
73 checks passed
@gabek
gabek deleted the gek/plugin-action-errors branch August 3, 2026 20:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants