Skip to content

에러 코드 — 모듈·백엔드 계약

This content is not available in your language yet.

각 절은 ### QuadNNNN — 메시지 원문(자리표시자는 {…}), 언제 나는가, 어떻게 고치는가. 번호로 찾으려면 색인.

Raw.Mapper: className must be a non-empty string (got {typeof(className)}) — quad-base/src/Claim.luau

  • 언제: q.Raw.Mapper(className)에 넘긴 className이 문자열이 아니거나 빈 문자열일 때(3.3까지는 q.newMapperClass). 백엔드의 타입드 q.Mapper "Frame"은 클래스 단계에서 먼저 Quad0278로 거부합니다.
  • 고치려면: 클래스 이름을 비어 있지 않은 문자열로 주세요.
  • 참고: q.Raw, q.Mapper

Claim: mapper descriptor was already used (descriptors are one-shot) — quad-base/src/Claim.luau

  • 언제: 이미 한 번 q.Claim에 쓰인 디스크립터(1회용)를 다시 쓰려고 할 때. 한 q.Claim 트리 안의 두 자리에 같은 디스크립터 값을 놓아도(M(q.MapperRoot)({ d, d })) 이 에러입니다.
  • 고치려면: 디스크립터 값을 저장해 재사용하지 말고, 필요하면 그것을 만드는 호출을 팩토리 함수로 감싸 매번 새로 만드세요.
  • 참고: q.Claim(inst, desc)

Claim: two mapper descriptors resolved to the same Instance {tostring(inst)} - each child needs exactly one descriptor — quad-base/src/Claim.luau

  • 언제: 서로 다른 두 디스크립터가 해석 결과 같은 Instance를 가리켰을 때 — 한 자식에 매퍼가 두 번 걸린 경우입니다.
  • 고치려면: 자식마다 디스크립터를 하나씩만 두세요.
  • 참고: q.Claim(inst, desc)

Claim: {tostring(inst)} is already claimed by quad - an Instance quad made (q.Elem) or already Claimed cannot be claimed again (leave it out of the descriptor and drive it separately, or dispose it and rebuild) — quad-base/src/Claim.luau

  • 언제: 디스크립터가 해석한 Instance가 같은 quad 모듈 인스턴스에 이미 소유돼 있을 때 — q.Elem으로 만들었거나 먼저 Claim된 것(루트도 자식도 해당)입니다. 다른 모듈 인스턴스(Quad.NewModule())가 소유한 것은 여기서 걸리지 않고 그대로 claim됩니다(정의되지 않은 동작 — Claim 계약 셋).
  • 고치려면: 그 자식을 디스크립터에서 빼고 따로 다루거나, q.dispose한 뒤 새로 만드세요.
  • 참고: q.Claim(inst, desc)

Claim: mapper props must be a table (got {typeof(desc._props)}) — quad-base/src/Claim.luau

  • 언제: 디스크립터의 props가 테이블이 아닐 때.
  • 고치려면: props에 테이블을 넘기세요.
  • 참고: q.Claim(inst, desc)

Claim: no child matched key {tostring(v._key)} under {tostring(inst)} (mapper {tostring(v._className)}) - a child with that name must also be a {tostring(v._className)} — quad-base/src/Claim.luau

  • 언제: 매퍼 디스크립터가 지목한 이름의 자식이 없거나, 이름은 맞는데 그 클래스(IsA)가 아닐 때.
  • 고치려면: 템플릿(claim 대상 Instance)에 그 이름·클래스의 자식이 실제로 있는지 확인하세요.
  • 참고: q.Claim(inst, desc)

Claim: first argument must be an Instance of the installed backend (got {typeof(inst)}) — quad-base/src/Claim.luau

  • 언제: q.Claim(inst, desc)의 첫 인자가 설치된 백엔드의 Instance가 아닐 때.
  • 고치려면: 실제 Instance를 넘기세요.
  • 참고: q.Claim(inst, desc)

Claim: second argument must be a mapper descriptor (q.Mapper "Frame" (key) {…}) — quad-base/src/Claim.luau

  • 언제: q.Claim(inst, desc)의 둘째 인자가 매퍼 디스크립터가 아닐 때.
  • 고치려면: q.Mapper "Class" (key)(props)(또는 q.Raw.Mapper)로 만든 디스크립터를 넘기세요.
  • 참고: q.Claim(inst, desc)

bindLifetime: inst must not be nil — quad-base/src/LifetimeHandle.luau

  • 언제: q.Backend.bindLifetime(inst, value)의 inst가 nil일 때 — 값을 묶으려면 살아 있는 요소가 있어야 합니다.
  • 고치려면: 실제 요소(Instance 등)를 넘기세요.
  • 참고: q.Backend.bindLifetime(inst, value)

bindLifetime: value must not be nil — quad-base/src/LifetimeHandle.luau

  • 언제: q.Backend.bindLifetime(inst, value)의 value가 nil일 때.
  • 고치려면: 실제로 묶을 값(Observer/Effect/Ref/Slot 등)을 넘기세요.
  • 참고: q.Backend.bindLifetime(inst, value)

bindLifetime: value is already subscribed — quad-base/src/LifetimeHandle.luau

  • 언제: 이미 전역 구독(:Subscribe()/:WeakSubscribe())으로 살아 있는 Observer/Effect를 다시 어떤 요소의 자리에 묶으려 할 때 — 전역 구독과 자리 바인딩은 겹칠 수 없습니다.
  • 고치려면: 구독 중인 핸들은 그대로 두거나, 새 핸들을 만들어 자리에 놓으세요.
  • 참고: q.Backend.bindLifetime(inst, value)

unbindLifetime: value must not be nil — quad-base/src/LifetimeHandle.luau

  • 언제: q.Backend.unbindLifetime(value)에 nil을 넘겼을 때 — 묶여 있지 않은 값은 no-op이지만, nil은 애초에 값이 아니라 인자 누락으로 취급합니다.
  • 고치려면: 실제로 풀려는 값을 넘기세요.
  • 참고: q.Backend.unbindLifetime(value)

{what}: this value was made by another quad module instance (one made with q.NewModule()) - values cannot cross instances — quad-base/src/ModuleIdentity.luau

  • 언제: 한 quad 모듈 인스턴스가 만든 Observer·Effect·Slot·State를 다른 인스턴스의 트리 자리(숫자 키, 프로퍼티 값, :List의 데이터, Slot의 원소 자리 등)에 놓았을 때. {what}은 그 값이 놓인 자리를 가리키는 이름("Observer"/"Slot" 등)입니다.
  • 고치려면: 값을 만든 인스턴스와 놓는 인스턴스를 같게 맞추세요. quad_base 사본이 둘 섞인 경우는 이 에러로 오지 않습니다 — 사본이 다르면 브랜드가 갈려 isState류가 거짓이라 Quad0076(빗나간 프로바이더 안내)·Quad0240·Quad0142류가 납니다.
  • 참고: q.NewModule()

quad: {name} is not available - no backend has installed {what} (install a provider with quad:UseProvider - a bare Quad.NewModule() has none{hint or ""}) — quad-base/src/NotInstalled.luau

  • 언제: 프로바이더를 설치하지 않은 Quad.NewModule()에서 백엔드가 채워야 할 op(생명주기 hold op, 엔진 op, 시간 op 등)나 백엔드 표면(q.Elem·q.Modifier·q.Spread·q.Mapper·q.OnChange·q.OnEvent·q.Out·q.ForClasses)을 부를 때 — {name}은 그 op나 표면의 이름입니다.
  • 고치려면: quad:UseProvider(...)로 백엔드를 설치하세요. 헤드리스 테스트라면 필요한 op를 채운 자기 프로바이더를 quad:UseProvider로 설치하세요 — 이 저장소의 테스트용 mock은 배포되지 않습니다(헤드리스 테스트).
  • 참고: q.Backend.bindLifetime(inst, value)

Relate:{method}: inst must not be nil — quad-base/src/Relate.luau

  • 언제: q.Relate()가 돌려준 릴레이션의 SetStrong/GetStrong/SetWeak/GetWeak 중 하나를 부를 때 inst 자리에 nil을 넘겼을 때. {method}는 실제로 부른 메소드 이름입니다.
  • 고치려면: 실제 요소를 inst 자리에 넘기세요.
  • 참고: q.Relate()

Relate:{method}: key must not be nil — quad-base/src/Relate.luau

  • 언제: 같은 네 메소드 중 하나를 부를 때 key 자리에 nil을 넘겼을 때.
  • 고치려면: 실제 키 값을 넘기세요.
  • 참고: q.Relate()

bindLifetime: value is already bound to this Instance (the same handle at two positions?) — quad-base/src/LifetimeHandle.luau

bindLifetime: value is already bound to another Instance — quad-base/src/LifetimeHandle.luau

  • 언제: 이미 어떤 요소의 자리에 묶여 있는 값을 같은 요소의 다른 자리에 또 묶으려 할 때 — 같은 핸들을 한 인스턴스 안 두 자리(q.Elem "Frame" { eff, eff } 등)에 놓은 경우입니다.
  • 언제: 이미 다른 요소의 자리에 묶여 있는 값을 또 다른 요소의 자리에 묶으려 할 때.
  • 고치려면: 새 핸들을 만들어 두 번째 자리에 놓으세요 — 하나의 핸들은 한 요소의 한 자리에만 묶일 수 있습니다.
  • 참고: q.Backend.bindLifetime(inst, value)

RunInit: initFn must be a function (got {typeof(initFn)}) — quad-base/src/init.luau

  • 언제: q:RunInit(initFn)의 initFn 자리가 함수가 아닐 때.
  • 고치려면: (module) -> any 모양의 함수를 넘기세요.
  • 참고: q:RunInit(initFn)

{who}: the function must return its extension table (got {typeof(extension)} - return an empty table if it adds nothing) — quad-base/src/init.luau

AddPlugin: the function must return its extension table (got {typeof(extension)} - return an empty table if it adds nothing) — quad-base/src/init.luau

  • 언제: q:UseProvider(providerFn)의 providerFn(self)나 q:AddPlugin(pluginFn)의 pluginFn(self)가 테이블을 반환하지 않았을 때 — 모듈을 고쳐 쓰기만 하고 아무것도 반환하지 않는 플러그인이 흔한 실수입니다. {who}는 부른 자리 이름입니다.
  • 고치려면: 확장 테이블을 반환하세요 — 아무것도 추가하지 않는다면 빈 테이블 {}을 반환하세요.
  • 참고: q:UseProvider(providerFn), q:AddPlugin(pluginFn)

AddPlugin: plugin must be a function (got {typeof(pluginFn)}) — quad-base/src/init.luau

  • 언제: q:AddPlugin(pluginFn)의 pluginFn 자리가 함수가 아닐 때.
  • 고치려면: (module) -> extension 모양의 함수를 넘기세요.
  • 참고: q:AddPlugin(pluginFn)

UseProvider: provider must be a function (got {typeof(providerFn)}) — quad-base/src/init.luau

  • 언제: q:UseProvider(providerFn)의 providerFn 자리가 함수가 아닐 때(UseProvider(nil)은 전에 조용히 통과했습니다).
  • 고치려면: (module) -> extension 모양의 함수를 넘기세요.
  • 참고: q:UseProvider(providerFn)

UseProvider: this Quad module already has a provider - a module cannot serve two backends — quad-base/src/init.luau

  • 언제: 이미 다른 프로바이더 함수(identity 기준)로 UseProvider를 부른 모듈에 다시 (다른) providerFn으로 UseProvider를 부를 때 — 같은 함수를 다시 넘기는 것은 멱등 no-op이라 에러가 아닙니다.
  • 고치려면: 모듈당 프로바이더는 하나입니다 — 새 모듈 인스턴스(q.NewModule())를 만들어 다른 백엔드를 설치하세요.
  • 참고: q:UseProvider(providerFn)

GetOrCreate: key must not be nil — quad-base/src/init.luau

  • 언제: q:GetOrCreate(key, build)의 key가 nil일 때.
  • 고치려면: 캐시 항목을 가를 값을 넘기세요 — 모듈 팩토리는 자기 build 함수, 사본끼리 나눠 쓸 킷 루트는 이름 문자열.
  • 참고: q:GetOrCreate(key, build)

GetOrCreate: build must be a function (got {typeof(build)}) — quad-base/src/init.luau

  • 언제: build 자리가 함수가 아닐 때.
  • 고치려면: (q) -> 값 모양의 함수를 넘기세요.
  • 참고: q:GetOrCreate(key, build)

GetOrCreate: "{tostring(key)}" is still being built - its build asked for itself (directly or through a sibling); move the late use into a function that runs after the build — quad-base/src/init.luau

  • 언제: 어떤 열쇠의 build가 도는 도중에 같은 열쇠로 다시 GetOrCreate를 불렀을 때 — 직접이든, 형제 모듈을 거쳐 돌아왔든. 그 시점엔 돌려줄 값이 없습니다.
  • 고치려면: 순환을 끊으세요. 서로를 쓰는 두 모듈이라면 한쪽은 빌드 중에 상대를 부르지 말고, 상대가 필요한 자리(이벤트 처리 함수 안 등 빌드가 끝난 뒤 도는 곳)에서 부르세요.
  • 참고: q:GetOrCreate(key, build)

GetOrCreate: the build for "{tostring(key)}" returned nil - return the value to cache (nil cannot be told apart from "not built yet") — quad-base/src/init.luau

  • 언제: build가 아무것도 돌려주지 않았을 때 — return을 빠뜨린 경우가 흔합니다.
  • 고치려면: 캐시할 값을 돌려주세요. 만들 것이 없다면 이 표면이 아니라 q:RunInit이 맞습니다.
  • 참고: q:GetOrCreate(key, build)

AssertProvider: name and versionPattern must be strings (got {typeof(name)}, {typeof(versionPattern)}) — quad-base/src/init.luau

  • 언제: q:AssertProvider(name, versionPattern)의 두 인자 중 하나가 문자열이 아닐 때.
  • 고치려면: 프로바이더 이름("quad-roblox")과 버전 패턴("4.0^.0^")을 문자열로 넘기세요.
  • 참고: q:AssertProvider(name, versionPattern)

AssertProvider: no provider is installed on this quad module (expected "{name}") - call q:UseProvider(...) in the game's setup module before handing q over — quad-base/src/init.luau

  • 언제: 받은 q에 프로바이더가 설치돼 있지 않을 때 — 게임의 설정 모듈이 UseProvider를 부르기 전의 q(또는 맨 Quad.NewModule())를 킷에 넘긴 경우입니다. 프로바이더가 설치돼 있어도 그 프로바이더가 q.Backend.provider를 적지 않으면 같은 에러입니다.
  • 고치려면: 게임의 설정 모듈에서 q:UseProvider(...)로 백엔드를 설치한 뒤 그 q를 넘기세요. 직접 만든 프로바이더라면 Backend.provider를 적게 하세요.
  • 참고: q:AssertProvider(name, versionPattern)

AssertProvider: the installed provider is "{tostring(info.name)}", expected "{name}" — quad-base/src/init.luau

  • 언제: q에 설치된 프로바이더가 요구한 것과 다른 백엔드일 때.
  • 고치려면: 그 소비자가 요구하는 백엔드를 설치한 q를 넘기세요 — 백엔드는 모듈 인스턴스당 하나입니다.
  • 참고: q:AssertProvider(name, versionPattern)

AssertProvider: provider "{name}" is version '{tostring(info.version)}', which does not match '{versionPattern}' — quad-base/src/init.luau

  • 언제: 설치된 프로바이더의 버전이 소비자가 요구하는 패턴에 맞지 않을 때.
  • 고치려면: 소비자가 요구하는 버전 범위의 프로바이더를 설치하거나, 지금 프로바이더 버전을 받는 소비자 버전으로 바꾸세요.
  • 참고: q:AssertProvider(name, versionPattern)

{fnName}: value must be a table, function or userdata (got {typeof(value)}) - a primitive has no identity to bind — quad-base/src/LifetimeHandle.luau

  • 언제: q.Backend.bindLifetime(inst, value)나 q.Backend.unbindLifetime(value)의 value가 숫자·문자열·불리언(또는 buffer·thread)일 때. 원시값은 같은 값이 프로그램 어디에나 있어 한 요소에 묶는다는 뜻이 서지 않습니다 — 전에는 통과해 무관한 두 바인딩이 같은 값으로 부딪치거나(Quad0232), 백엔드가 자기 부기에 쓰는 자리를 덮거나, NaN이면 VM 에러로 죽었습니다. {fnName}은 bindLifetime 또는 unbindLifetime입니다. 묶을 수 없는 값이므로 푸는 것도 같은 에러입니다.
  • 고치려면: 수명을 묶을 값은 quad 값(Observer/Effect/Ref/Slot 등)·인스턴스·클로저·테이블로 넘기세요. 원시값의 수명을 따로 관리할 일은 없습니다 — 그 값을 쥔 테이블이나 클로저를 묶으세요.
  • 참고: q.Backend.bindLifetime(inst, value)

업데이트로 폐기되어 더는 나오지 않는 에러 번호입니다. 옛 번호를 만났다면 아래 목록에서 지금 쓰는 번호를 찾으세요.

폐기된 번호 목록
  • Quad0031 — 이제 던지지 않습니다. q.Claim이 해석 단계에서 디스크립터 props의 숫자 키 도메인을 잠깐 검사했다가, 해석 단계를 디스크립터를 찾아 실제 Instance로 바꾸는 매핑만 하는 단계로 되돌렸습니다. 양의 정수가 아닌 숫자 키([0], [2.5], 음수)는 그 자리 값이 디스크립터든 아니든 Quad0085가 그 props를 적용하는 단계에서 거부합니다 — claim은 이미 일어난 뒤입니다. 이 번호는 다른 에러에 다시 쓰지 않습니다. 참고: q.Claim(inst, desc). 옛 문구: Claim: array keys must be positive integers (got {i})
  • Quad0211 — 4.0.0부터 같은 실수는 Quad0209입니다. 옛 문구: AddPlugin: the function must return its extension table (got {typeof(extension)} - return an empty table if it adds nothing)
  • Quad0233 — 4.0.0부터 같은 실수는 Quad0232입니다. 옛 문구: bindLifetime: value is already bound to another Instance