Pinned Data in Node Inspector
The Node Inspector tab shows a Pinned Data section below the Output Data section. This section only appears when NodeInspectorData.pinnedData is non-null. It displays the pinned data as a collapsible, syntax-highlighted JSON viewer.
NodeInspectorData Type
// nodeInspector.ts (flow-observer-core)
export interface NodeInspectorData {
nodeId : string;
nodeLabel : string;
status : NodeExecutionStatus;
inputData : unknown; // Data the node received as input
outputData : unknown; // Ephemeral output from this run
pinnedData : unknown | null; // Persistent pinned data — null if not set
logs : LogEntry[];
metrics : NodeMetrics;
}
How pinnedData Is Loaded
When the user clicks a node in the Observer Panel, handleNodeClick fetches all inspector data including pinned data from the REST API:
// NodeInspectorTabContent.tsx
async function handleNodeClick(nodeId: string) {
const data = await executionApiClient.getNodeInspectorData(executionId, nodeId);
// data.pinnedData comes from the API — it reads Process_NodePinnedData for this processId+nodeId
useExecutionStore.getState().setNodeInspectorData(data);
}
// API endpoint (backend)
// GET /api/executions/{executionId}/nodes/{nodeId}/inspector
// Response includes: { inputData, outputData, pinnedData, logs, metrics, ... }
Pinned Data Section Rendering
// NodeInspectorTabContent.tsx (Pinned Data section)
function PinnedDataSection({ pinnedData }: { pinnedData: unknown }) {
const [isExpanded, setIsExpanded] = useState(false);
// Section only rendered when pinnedData is non-null
if (pinnedData === null || pinnedData === undefined) {
return null;
}
return (
<div className="inspector-section">
<div
className="inspector-section-header"
onClick={() => setIsExpanded(prev => !prev)}
>
<span>Pinned Data</span>
<span className="badge badge-pinned">Persistent</span>
<i className={isExpanded ? 'fa-chevron-up' : 'fa-chevron-down'} />
</div>
{isExpanded && (
<JsonViewer data={pinnedData} />
)}
</div>
);
}
Pinned Data Badge
The Pinned Data section header shows a "Persistent" badge to distinguish it visually from the ephemeral Output Data section. This helps workflow designers understand at a glance that this data survives across runs.
| Section | Badge | When Visible |
|---|---|---|
| Input Data | This Run | Always (when node has been executed) |
| Output Data | This Run | When output is non-null for this execution |
| Pinned Data | Persistent | Only when pinnedData !== null |
| Node Logs | — | Always (may be empty list) |
| Node Metrics | — | Always (shows duration, retries, result) |
Pinned Data in Historical Executions
When viewing a past execution, the Inspector API still fetches pinned data from Process_NodePinnedData — but this returns the CURRENT pinned data, not what was pinned at the time of the historical run. If the workflow has run many times since the historical execution, the pinned data shown in the inspector reflects the most recent write, not the historical run's output.
Process_NodePinnedData table stores only the latest value (one row per node). The Node Inspector always shows what is currently pinned — it has no history of previous pinned values. If point-in-time auditability of pinned data is needed, write it to a separate audit table as well.