pool_role_unknown

The running jobjob_7Hq2 · delivered · document.fr-CA.pdf · $49.00 charged

A Service's role names a Pool that has no role by that name, so no member could ever be offered its Task.

FixFails inExit
Name the role as the Pool does, or add it to the Pool's roles.services/translation.ts:10 · roles.sworn1

Owned by Pool(): your marketplace: the page that explains what this gate holds.

npx services.dev check
  ✗ A step performs a reserved act, and no role that does it holds the credential its row reserves it to. Give the step to a role that holds the credential, or set the role's credential to one that meets it. sign performs sign, reserved to sworn translator (rules 2026-10), and the sworn role holds no credential.
    at services/translation.ts:10 · roles.sworn.credential
  ✗ A Service's role names a Pool that has no role by that name, so no member could ever be offered its Task. Name the role as the Pool does, or add it to the Pool's roles. translation's role sworn names the translators Pool, which fills translator.
    at services/translation.ts:10 · roles.sworn
✗ 2 to fix

The same file failed reserved_act_unstaffed in the same run. Each has its own page.

services/translation.ts
import { Service } from 'services.dev'
import { translators } from '../pools/translators.ts'
import rules from '../rules.ts'

export default Service({
  name: 'Translation',
  input: { document: 'file', to: 'language: a BCP 47 tag, such as fr-CA' },
  output: { document: 'file' },
  rules,
  roles: { sworn: { pool: translators } },
  deliver: {
    translate: 'ai',
    harden: { review: 'adversarial', lenses: ['meaning', 'terms'] },
    sign: { by: 'sworn', stamp: true },
  },
  price: 89,
})
git add -A && git diff --staged
diff --git a/services/translation.ts b/services/translation.ts
index 2f71f3d..e68b75e 100644
--- a/services/translation.ts
+++ b/services/translation.ts
@@ -7,11 +7,11 @@ export default Service({
   input: { document: 'file', to: 'language: a BCP 47 tag, such as fr-CA' },
   output: { document: 'file' },
   rules,
-  roles: { sworn: { pool: translators } },
+  roles: { translator: { pool: translators } },
   deliver: {
     translate: 'ai',
     harden: { review: 'adversarial', lenses: ['meaning', 'terms'] },
-    sign: { by: 'sworn', stamp: true },
+    sign: { by: 'translator', stamp: true },
   },
   price: 89,
 })
npx services.dev check
✓ ready to sell · 1 Service · it keeps at least 80% of every job
pools/translators.ts
import { Pool } from 'services.dev'

export const translators = Pool({
  name: 'translators',
  roles: { translator: { credential: 'sworn translator' } },
  join: { name: 'text', languages: 'language[]' },
  verify: 'https://verify.example.test/translators',
  fill: ['raise 10% 2h', 'widen 4h'],
})
rules.ts
import { Rules } from 'services.dev'

export default Rules({
  version: '2026-10',
  services: {
    translation: {
      sign: { reserved: 'sworn translator', where: '*', position: 'A sworn translator signs a translation filed with a registry.' },
    },
  },
})

How the legal example passes this gate, in lines read from its files.

examples/legal/pools/attorneys.ts
roles: {
  attorney: { credential: 'bar admission' },
  practitioner: { credential: ['patent attorney', 'patent agent'], where: '*' },
// …
  student: { credential: 'law school enrollment' },
examples/legal/services/contract-review.ts
roles: { attorney: { pool: attorneys, pay: 50 } },

Read them in context: The attorneys' Pool, Contract review.

npx services.dev check --json · the pool_role_unknown failure
{
  "code": "pool_role_unknown",
  "reason": "A Service's role names a Pool that has no role by that name, so no member could ever be offered its Task.",
  "next": "Name the role as the Pool does, or add it to the Pool's roles. translation's role sworn names the translators Pool, which fills translator.",
  "doc_url": "https://services.dev/docs/reference/check/pool_role_unknown",
  "file": "services/translation.ts",
  "line": 10,
  "path": "roles.sworn"
}
The whole document check --json prints
npx services.dev check --json
{
  "ai": {
    "cents_per_call": 42,
    "simulated": true
  },
  "mcp": {
    "tools": 13,
    "tokens": 4488,
    "sandbox": 9,
    "budget": 8000
  },
  "files": [
    {
      "path": "rules.ts",
      "lines": 6,
      "kind": "rules",
      "says": "rules 2026-10 · 1 Service · 1 row"
    },
    {
      "path": "pools/translators.ts",