Skip to content

plugin docs: stdin/stdout uses type:"body" inside callbacks#4

Open
martinrode wants to merge 2 commits into
mainfrom
martin-ai/plugin-callback-stdin-doc-20260609
Open

plugin docs: stdin/stdout uses type:"body" inside callbacks#4
martinrode wants to merge 2 commits into
mainfrom
martin-ai/plugin-callback-stdin-doc-20260609

Conversation

@martinrode

@martinrode martinrode commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Triggered by Andre Buhl hitting the documented form while writing his first server-side plugin against a Windows-local fylr instance.

The "Format of manifest.yml" example placed the extension-style URL form (stdin.url: "%_input.url%" / stdout.url: "%_output.url%") inside both callbacks.transition_db_pre_save and callbacks.db_pre_save example blocks. That form works in extensions: because fylr exposes the input/output as on-the-fly HTTP endpoints there. In callbacks the same placeholder is not substituted — the execserver receives the literal string and fails to GET stdin from it:

Could not prepare stdin "%_input.url%": parse "%_input.url%": invalid URL escape "%_i"

The two callback examples now use type: "body", matching the IUCN plugin's manifest (easydb-custom-data-type-iucn/manifest.yml) and the fylr-internal cookbooks (resources/baseconfig/fas/cookbooks/dot.yml:14ff).

Added a hint block near the top of the Callbacks section that:

  1. Names the extension vs. callback split explicitly
  2. Quotes the actual error message so the next developer who runs into it can search for it and land on this hint directly

The extensions: example near the top of the file is unchanged — that one was already using the correct URL form.

Test plan

  • Render preview on GitBook and confirm the warning hint shows up correctly under the "Callbacks" heading
  • Confirm the two callbacks YAML blocks now read type: "body" for stdin and stdout
  • Confirm the extensions: example was left intact

🤖 Generated with Claude Code

martin-ai added 2 commits June 9, 2026 12:18
…form)

The "Format of manifest.yml" example showed `stdin.url: "%_input.url%"` and
`stdout.url: "%_output.url%"` inside the `callbacks:` block. That syntax is
correct for `extensions:` (which expose the input/output as HTTP endpoints
via the on-the-fly /reader and /writer mechanisms) but not for callbacks.

In the callback dispatch path the placeholder is not substituted, and fylr
attempts to use the literal "%_input.url%" as the URL to GET stdin from.
The resulting `parse "%_input.url%": invalid URL escape "%_i"` error is what
a plugin developer building a `db_pre_save` callback hit during local
testing.

Update both `transition_db_pre_save` and `db_pre_save` examples to use
`type: "body"` (matching the IUCN plugin's `manifest.yml` and the dot.yml
cookbook). Add a hint near the start of the Callbacks section explicitly
calling out the extension-vs-callback transport difference and quoting the
actual error message so the next person who hits it can search for it.

The `extensions:` example at the top of the file is left unchanged — that
one was already correct.
The "Format of manifest.yml" callback examples referenced their script
files by bare relative paths (`value: "set_comment.js"`). At runtime
fylr's execserver runs the plugin process with cwd set to the per-job
working directory under `tempDir` — *not* the plugin's directory — so the
runtime can't find the script and fails with the language-specific
"module not found" error (Node.js: `MODULE_NOT_FOUND` from
`Module._load`; Python: `FileNotFoundError`; etc.).

The fix is the `%_exec.pluginDir%` replacement, which already exists in
`internal/server/execserver/exec.go:130` and is used in working real-world
plugins (e.g. `easydb-custom-data-type-iucn/manifest.yml`:
`value: "%_exec.pluginDir%/src/server/main-fylr.py"`). It was just never
documented on the plugin doc page.

Two changes:

1. Add `%_exec.pluginDir%` to the replacement table near the top of the
   page, with a one-line explanation of *why* you need it (so readers
   don't have to hit the runtime error first to learn the rule).
2. Update the two callback example blocks to prefix their script paths
   with `%_exec.pluginDir%/`, matching what an actually-working plugin
   looks like.

The extension example at the top of the file already used absolute
referencing for `%info.json%`, so the change there is just adding the
prefix on the script-file `value`.
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.

1 participant