Description
When importing a config file into a named workspace via mockd workspace use <id> + mockd import <file>, mocks receive the correct workspaceId, but statefulResources (tables) and customOperations are always registered under the empty/default workspace "".
As a result, when a matched mock (with WorkspaceID = "A") tries to resolve its stateful table or custom operation, lookups fail with StatusNotFound because neither StateStore.Get nor Bridge.executeCustom fall back to the default workspace.
Steps to Reproduce
- Create a config file
exchange-a.yaml with mocks, tables, and custom operations:
mocks:
- id: place-order
type: http
http:
matcher:
method: POST
path: /orders
statefulBinding:
table: orders
action: create
statefulResources:
- name: orders
idField: id
customOperations:
- name: CancelOrder
steps:
- action: delete
resource: orders
id: "{{input.orderId}}"
- Start mockd and create a workspace:
mockd start
mockd workspace create -n exchange-a
mockd workspace use <exchange-a-id>
mockd import exchange-a.yaml
- Call the mock:
curl -X POST http://localhost:4280/orders -d '{"symbol":"BTC"}'
- Call a custom operation endpoint bound to
CancelOrder.
Expected Behavior
POST /orders creates an item in the orders table and returns 201.
- Custom operation
CancelOrder executes successfully.
Actual Behavior
POST /orders returns 404 — StateStore.Get("exchange-a-id", "orders") returns nil
because the table is registered under workspace "", not "exchange-a-id".
- Custom operation returns
404 — Bridge.executeCustom looks up
b.customOps["exchange-a-id"]["CancelOrder"], finds nothing, and has no fallback.
Environment
- OS: Windows 11
- Go Version: 1.25.0
- mockd Version: v0.6.4
- Installation Method: Docker
Configuration
# exchange-a.yaml
mocks:
- id: place-order
type: http
http:
matcher:
method: POST
path: /orders
statefulBinding:
table: orders
action: create
statefulResources:
- name: orders
idField: id
customOperations:
- name: CancelOrder
steps:
- action: delete
resource: orders
id: "{{input.orderId}}"
Logs
# Expected after POST /orders:
404 No mock matched the request ← or stateful resource not found
Additional Context
There are two possible solutions to this issue:
- Fallback to the default workspace
- Specify the workspace when importing resources (as is done for mocks)
| Criterion |
Fallback |
Explicit workspaceId |
| Complexity |
Less code |
More code |
| Clarity |
Implicit |
Explicit — better for debugging |
| Error risk |
May hide a typo in the table/operation name |
Error is immediately apparent |
| Backward compatibility |
Works for configs without workspaceId |
Requires configuration update |
| Data isolation |
None (different workspaces may accidentally see each other's tables) |
Full isolation |
I can help you fix the issue if you confirm it and select your preferred solution.
Description
When importing a config file into a named workspace via
mockd workspace use <id>+mockd import <file>, mocks receive the correctworkspaceId, butstatefulResources(tables) andcustomOperationsare always registered under the empty/default workspace"".As a result, when a matched mock (with
WorkspaceID = "A") tries to resolve its stateful table or custom operation, lookups fail withStatusNotFoundbecause neitherStateStore.GetnorBridge.executeCustomfall back to the default workspace.Steps to Reproduce
exchange-a.yamlwith mocks, tables, and custom operations:curl -X POST http://localhost:4280/orders -d '{"symbol":"BTC"}'CancelOrder.Expected Behavior
POST /orderscreates an item in theorderstable and returns201.CancelOrderexecutes successfully.Actual Behavior
POST /ordersreturns404—StateStore.Get("exchange-a-id", "orders")returnsnilbecause the table is registered under workspace
"", not"exchange-a-id".404—Bridge.executeCustomlooks upb.customOps["exchange-a-id"]["CancelOrder"], finds nothing, and has no fallback.Environment
Configuration
Logs
Additional Context
There are two possible solutions to this issue:
I can help you fix the issue if you confirm it and select your preferred solution.