#Skill scripts are failing with module not found.

1 messages · Page 1 of 1 (latest)

thorn garden
#

My skill has some python scripts inside scripts/ directory. On smaller models (eg. gemma), the python script invocation fails with module not found error. When I run it on bigger model e.g gpt-5.4 or onnnet 4.5, model auto fixes it and is able to run python script. Is there any workaround for this? Tia

ModuleNotFoundError: No module named openclaw_trent'

Skill: https://clawhub.ai/trent-ai-release/trentclaw

river ingotBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> âś… Mark Solution

shy fernBOT
#

Yep — this is usually a skill packaging/instructions issue, not really a Python issue.

Smaller models often run the Python snippet from the workspace cwd, so Python can’t see the module inside the skill folder. Bigger models “fix” it by guessing cd / PYTHONPATH / sys.path automatically.

Workaround: make the skill instructions deterministic. In SKILL.md, before any Python snippets, tell the model to run Python with the skill’s scripts dir on PYTHONPATH:

cd "{baseDir}"
PYTHONPATH="{baseDir}/scripts:${PYTHONPATH:-}" python3 - <<'PY'
from openclaw_trent.openclaw_config.collector import collect_openclaw_metadata
# ...rest of snippet...
PY

Even better: add a tiny wrapper in the skill, e.g. scripts/trent_phase1.py, and have the skill invoke only:

#
cd "{baseDir}"
PYTHONPATH="{baseDir}/scripts:${PYTHONPATH:-}" python3 scripts/trent_phase1.py

That removes the “smart model must infer the import path” step. Also make sure the directory is actually scripts/ — you wrote scipts/ in the message, so worth checking for a typo too.

For maximum robustness, each script can also add its own path at the top:

from pathlib import Path
import sys
sys.path.insert(0, str(Path(__file__).resolve().parent))

Docs note: skills can use {baseDir} to reference the skill folder: https://docs.openclaw.ai/tools/skills

#

If it still fails after that, share openclaw --version and the skill folder layout (find skills/trentclaw -maxdepth 3 -type f).

thorn garden
#

Yes dir is scripts. it was typo earlier

shy fernBOT
#

Got it 👍 then I’d bet on import path/cwd.

For this specific layout, the robust pattern is:

cd "{baseDir}"
PYTHONPATH="{baseDir}/scripts:${PYTHONPATH:-}" python3 - <<'PY'
from openclaw_trent.openclaw_config.collector import collect_openclaw_metadata
PY

Or if you’re invoking files:

cd "{baseDir}"
PYTHONPATH="{baseDir}/scripts:${PYTHONPATH:-}" python3 scripts/phase1.py
#

The key bit is PYTHONPATH="{baseDir}/scripts..." because your import is openclaw_trent..., and that package appears to live under scripts/openclaw_trent/. Running from the workspace alone won’t put that directory on Python’s module search path.

If you want smaller models to stop improvising entirely, I’d add an explicit “Execution rule” section to the skill:

## Execution rule
Always run Python commands from this skill with:
`cd "{baseDir}" && PYTHONPATH="{baseDir}/scripts:${PYTHONPATH:-}" python3 ...`
Never run these snippets from another working directory without setting PYTHONPATH.

That should make Gemma-level models much less likely to trip over it.

thorn garden
#

will there be any regression?

shy fernBOT
#

Very unlikely, if you scope it to that one command.

PYTHONPATH="{baseDir}/scripts:${PYTHONPATH:-}" python3 ... only affects that Python process and its children. It does not change the user’s shell, OpenClaw config, or global Python install.

Possible edge cases:

  • If another installed Python package has the same top-level name openclaw_trent, putting {baseDir}/scripts first means the bundled skill copy wins. That’s usually what you want.
  • If the script relies on being run from some other cwd, cd "{baseDir}" could change relative file behavior. For skill-bundled scripts, {baseDir} is normally the safest cwd.
  • If users run inside a sandbox/container, Python still needs to exist there, but this change doesn’t make that worse.

So I’d call it a safe fix. The most regression-resistant version is a wrapper script that sets sys.path from __file__, because then it works no matter where the model runs it from.

thorn garden
#

cd "{baseDir}"
PYTHONPATH="{baseDir}/scripts:${PYTHONPATH:-}" python3 - <<'PY'
from openclaw_trent.openclaw_config.collector import collect_openclaw_metadata
PY

does this go in snippet?

shy fernBOT
#

Yes — put that wrapper around each Python snippet in SKILL.md.

So instead of showing the model only this:

from openclaw_trent.openclaw_config.collector import collect_openclaw_metadata

show it as an executable shell block:

cd "{baseDir}"
PYTHONPATH="{baseDir}/scripts:${PYTHONPATH:-}" python3 - <<'PY'
from openclaw_trent.openclaw_config.collector import collect_openclaw_metadata

metadata = collect_openclaw_metadata()