Skip to content

Skills gaps causing repeated failures in Motoko blog app generation (follow-up to #35) #37

@marc0olo

Description

@marc0olo

Context

This is a follow-up to #35. That issue documented 15 errors building a Rust + React ICP blog app where Claude Code had skills installed locally but ignored them. This issue documents a new session building a Motoko + Vanilla JS blog app where skills were not installed locally but were fetched via WebFetch from skills.internetcomputer.org — and we still hit 8 errors across 8 deploy attempts.

The skills were fetched proactively from the start (before writing any code), which eliminated several error classes from #35 (wrong package versions, wrong import paths). But new gaps emerged, particularly around Motoko APIs and environment-specific pitfalls.

Session Stats

  • Errors: 8
  • User prompts to fix: 5 error-fix rounds after initial generation
  • Deploy attempts: 8 before working app
  • Skills fetched: 4 (icp-cli, internet-identity, asset-canister, stable-memory) + index.json
  • Estimated tokens: ~300-400k

Errors Encountered

# Error Skill Gap
1 YAML && HTML-encoded by icp-cli in build commands icp-cli skill doesn't warn about this — agent used cd src/frontend && npm install which icp-cli encoded as &&
2 Missing [toolchain] section in mops.toml No skill covers mops toolchain setup
3 moc 0.13.6 too old for core@2.0.0 (requires >= 1.0.0) stable-memory skill pins core = "2.0.0" but doesn't specify compatible moc version
4 mo:core 2.0.0 API hallucinations — List.pushBack, Map.set, Array.thaw/freeze don't exist No Motoko skill exists. Agent hallucinated from older base library training data. Actual API: List.add, Map.add (for upsert), Map.take, Array.toVarArray
5 fetch Illegal Invocation in production bundle internet-identity skill shows HttpAgent.create() without fetch: window.fetch.bind(window)
6 Wrong II canister ID fallback (be2us-64aaa-aaaaa-qaabq-cai) internet-identity skill hardcodes this fallback, but local II is actually at rdmx6-jaaaa-aaaaa-aaadq-cai
7 shouldFetchRootKey cross-origin issue (initial misdiagnosis of #5) Skills don't explain the relationship between ic_env cookie root key and shouldFetchRootKey
8 No admin init flow in UI (CLI identity ≠ browser II identity) Not a skill gap per se, but a common pattern that could be documented

Errors Shared with Issue #35

Two errors appeared in both sessions despite different tech stacks:

  1. fetch Illegal Invocation (Building an ICP Blog App with Claude Code: A Case Study in What Goes Wrong Without Skills #35 error docs: HTTPS outcalls concept page #12, this session error docs: getting-started quickstart page #5) — This is the most impactful recurring issue. The internet-identity skill's HttpAgent.create() example needs fetch: window.fetch.bind(window) added.

  2. Wrong II canister ID (Building an ICP Blog App with Claude Code: A Case Study in What Goes Wrong Without Skills #35 error feat: agent-friendly documentation (llms.txt + markdown endpoints) #14, this session error docs: getting-started project structure page #6) — The hardcoded fallback in the skill is wrong for local development.

Errors Eliminated vs Issue #35

Because skills were fetched upfront, these #35 errors did not occur:

  • Wrong package versions (@icp-sdk/auth@^0.1.0) — skill had correct versions
  • Wrong import paths (@icp-sdk/auth vs @icp-sdk/auth/client) — skill had correct paths
  • Wrong project structure (canister.yaml vs icp.yaml) — skill had correct format
  • Missing workspace Cargo.toml — N/A (Motoko, not Rust)
  • tsc before bindings — N/A (vanilla JS, no TypeScript)

This confirms that skills do prevent errors when used — the remaining errors are gaps in the skills themselves.

Recommended Skill Improvements

1. internet-identity skill — Fix recurring errors

  const agent = await HttpAgent.create({
    identity,
    host: isLocal ? "http://localhost:8000" : "https://icp-api.io",
+   fetch: window.fetch.bind(window),
    ...(isLocal && { shouldFetchRootKey: true, verifyQuerySignatures: false }),
  });
- const iiCanisterId = canisterEnv?.["PUBLIC_CANISTER_ID:internet_identity"]
-   ?? "be2us-64aaa-aaaaa-qaabq-cai";
+ const iiCanisterId = canisterEnv?.["PUBLIC_CANISTER_ID:internet_identity"]
+   ?? "rdmx6-jaaaa-aaaaa-aaadq-cai";

Add a "Common Pitfalls" section:

  • fetch: window.fetch.bind(window) is required in production Vite/webpack bundles
  • CLI identity and browser II identity are different principals — provide UI for admin init
  • Explain ic_env cookie root key vs shouldFetchRootKey (prefer cookie when available)

2. New: motoko skill (or expand stable-memory)

The biggest error source (error #4) was hallucinated Motoko APIs. A Motoko skill should cover:

  • mo:core 2.0.0 API quick reference (at minimum List, Map, Array method names)
  • mops.toml configuration including [toolchain] section with compatible moc version
  • persistent actor pattern (currently in stable-memory but incomplete)
  • Common type patterns ({#less; #equal; #greater} for comparators)

3. icp-cli skill — Build command escaping

Add a warning about special characters in YAML build commands:

# DON'T: && may be HTML-encoded by some tools
build:
  - cd src/frontend && npm install && npm run build

# DO: use a shell script or separate commands
build:
  - sh src/frontend/build.sh

4. stable-memory skill — Pin compatible toolchain

  [package]
  name = "my-project"
  version = "0.1.0"

+ [toolchain]
+ moc = "1.3.0"
+
  [dependencies]
  core = "2.0.0"

Comparison Summary

Metric #35 (Rust, skills installed but ignored) This session (Motoko, skills fetched via WebFetch)
Errors 15 8
Deploy attempts ~8 8
Shared errors fetch binding, II canister ID Same two
Unique errors Wrong versions, imports, structure mo:core API hallucinations, mops toolchain
Root cause Agent didn't use available skills Skills lack Motoko coverage + have wrong defaults

Takeaway

Proactively fetching skills via WebFetch cut errors nearly in half (15 → 8). The remaining errors fall into two categories:

  1. Bugs in existing skills (fetch binding, wrong II canister ID) — easily fixable, high impact since they affect every session
  2. Missing skill coverage (Motoko APIs, mops toolchain) — requires a new motoko skill

The llms.txtindex.json → on-demand skill fetch pattern discussed in #35 comments works. The skills themselves just need these gaps filled.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions