Published on

ComfyUI 워크플로 JSON 깨짐 복구 실전

Authors

ComfyUI를 오래 쓰다 보면 어느 날 갑자기 워크플로 JSON이 열리지 않거나, Load 시 에러가 나면서 노드가 통째로 사라지는 경험을 하게 됩니다. 특히 대형 워크플로(노드 수가 많고, 커스텀 노드가 섞이고, 프롬프트 메타데이터까지 포함된 경우)일수록 저장/복사/전송 과정에서 JSON이 쉽게 깨집니다.

이 글에서는 “깨진 ComfyUI 워크플로 JSON”을 최대한 원형에 가깝게 복구하는 실전 절차를 다룹니다. 단순히 JSON 포맷터 돌리는 수준이 아니라, 잘린 파일(EOF truncate), 잘못된 따옴표/역슬래시, 인코딩 문제, 중복/누락 괄호까지 현실적으로 자주 만나는 케이스를 기준으로 정리합니다.

운영 관점에서의 장애 대응 루틴도 중요합니다. 비슷한 맥락으로 배포 스크립트의 실패를 조기에 잡는 방법은 bash set -euo pipefail로 배포 스크립트 실패 잡기도 참고할 만합니다.

1) ComfyUI 워크플로 JSON이 깨지는 대표 원인

1-1. 저장 중 강제 종료로 인한 파일 잘림

  • 브라우저 탭 강제 종료
  • ComfyUI 서버 재시작/크래시
  • 네트워크 끊김(원격 접속 환경)

이 경우 파일 끝부분이 잘려서 }]가 부족합니다. 가장 흔한 형태입니다.

1-2. 메신저/노트 앱 복붙으로 인한 이스케이프 파손

  • Slack/Notion/메일에 붙여넣는 과정에서 \n, \uXXXX 같은 이스케이프가 변형
  • “스마트 따옴표”로 " 로 바뀜

1-3. 커스텀 노드 업데이트로 스키마가 달라짐

JSON은 정상인데, 특정 노드 타입이 없어 로딩이 실패하거나 일부 노드가 누락된 것처럼 보일 수 있습니다.

1-4. JSON이 아닌 것을 JSON로 착각

ComfyUI에서 공유되는 파일/텍스트는 크게 3종류가 섞입니다.

  • 워크플로 JSON
  • API 프롬프트 JSON(서버에 prompt로 보내는 형태)
  • 이미지에 박힌 메타데이터(Compressed/Encoded)

서로 구조가 달라서 “유효한 JSON인데 ComfyUI에서 안 열림”이 발생할 수 있습니다.

2) 복구 전, 반드시 해야 할 안전 조치

  1. 깨진 파일을 원본 그대로 복사해 보관
  2. 편집은 복사본에서만 진행
  3. 가능하면 Git으로 버전 관리(워크플로도 코드처럼 다루는 게 최선)
cp workflow.json workflow.json.bak
# 가능하면 폴더를 git으로 관리
git init
git add workflow.json.bak
git commit -m "backup broken workflow"

3) 1차 진단: JSON이 정말 깨졌는지 빠르게 확인

3-1. jq로 파싱 테스트

가장 빠르고 확실합니다.

jq . workflow.json > /dev/null
# 성공하면 exit code 0
# 실패하면 에러 위치(라인/컬럼)가 나옵니다.

에러가 parse error: Unfinished JSON term at EOF 류면 거의 100% 파일이 잘린 케이스입니다.

3-2. Python으로 에러 위치 확인

jq가 없다면 Python으로도 충분합니다.

python - <<'PY'
import json, sys
p='workflow.json'
try:
    json.load(open(p,'r',encoding='utf-8'))
    print('OK')
except Exception as e:
    print('FAIL:', e)
PY

4) 잘린 JSON(EOF truncate) 복구: 괄호 균형 맞추기

잘린 파일은 “끝이 없다”가 문제이므로, 괄호/대괄호 균형을 맞춰 닫아주는 방식이 1차 복구로 가장 효과적입니다.

4-1. 간단 스크립트: 부족한 } ] 자동 보정

아래 스크립트는 문자열 리터럴 내부는 최대한 건드리지 않고(완벽하진 않지만), 전체 텍스트에서 { } [ ] 수를 보고 부족한 닫는 괄호를 뒤에 붙입니다.

# fix_brackets.py
import sys

src = open(sys.argv[1], 'r', encoding='utf-8', errors='replace').read()

open_curly = src.count('{')
close_curly = src.count('}')
open_square = src.count('[')
close_square = src.count(']')

need_curly = max(0, open_curly - close_curly)
need_square = max(0, open_square - close_square)

fixed = src + (']' * need_square) + ('}' * need_curly)

out = sys.argv[2]
open(out, 'w', encoding='utf-8').write(fixed)
print('added ]:', need_square, 'added }:', need_curly)
python fix_brackets.py workflow.json workflow.fixed.json
jq . workflow.fixed.json > /dev/null && echo "parse ok"

이게 통과되면, 일단 JSON은 다시 “읽히는 상태”가 됩니다. 다만 마지막 오브젝트가 중간에 잘렸다면(예: 문자열이 반만 남음), 파싱이 여전히 실패할 수 있습니다.

4-2. 마지막이 문자열 중간에서 잘린 경우: 마지막 라인 절단

문자열이 열려 있는 상태로 파일이 끝나면, 괄호를 붙여도 파싱이 안 됩니다. 이때는 마지막으로 완결된 구조까지만 남기고 버리는 방식이 현실적입니다.

전략은 다음과 같습니다.

  • 파서가 에러를 내는 위치(라인/컬럼) 근처를 확인
  • 마지막 몇 줄을 과감히 삭제하고 다시 시도
# 마지막 50줄을 별도 파일로 확인
tail -n 50 workflow.json | nl -ba

# (예시) 마지막 10줄을 제거한 새 파일 생성
head -n -10 workflow.json > workflow.trim.json
jq . workflow.trim.json > /dev/null

이 방식은 일부 노드/설정이 유실될 수 있지만, “아예 못 여는 상태”를 “대부분 열리는 상태”로 바꾸는 데 유효합니다.

5) 따옴표/이스케이프 깨짐 복구: 스마트 따옴표, 역슬래시

5-1. 스마트 따옴표를 ASCII 따옴표로 치환

Notion/문서 편집기에서 흔합니다.

python - <<'PY'
import re
p='workflow.json'
s=open(p,'r',encoding='utf-8',errors='replace').read()
# 스마트 따옴표 치환
s=s.replace('“','"').replace('”','"').replace('’',"'").replace('‘',"'")
open('workflow.quotes.fixed.json','w',encoding='utf-8').write(s)
print('done')
PY

jq . workflow.quotes.fixed.json > /dev/null

5-2. 역슬래시가 소실된 경우

예를 들어 \n이 실제 줄바꿈으로 변해 JSON 문자열이 깨지는 경우가 있습니다. 이건 자동 복구가 까다롭고, 보통은 **깨진 문자열이 들어간 필드(예: prompt 텍스트)**를 찾아서 해당 문자열을 통째로 다시 감싸거나 제거해야 합니다.

팁:

  • jq 에러 위치 라인을 기준으로 해당 줄을 열어보면, 문자열이 중간에 끊겨 있는 경우가 많습니다.
  • 복구 우선순위는 “워크플로 구조(nodes/links)”를 살리는 것이고, 프롬프트 텍스트 일부는 포기하는 게 시간 대비 효율적입니다.

6) “JSON은 정상인데 ComfyUI에서 안 열림” 케이스

JSON 파싱은 되는데 ComfyUI에서 로딩이 실패한다면, 구조 문제가 아니라 노드 정의/버전 문제일 가능성이 큽니다.

6-1. 커스텀 노드 누락

  • 워크플로에 포함된 커스텀 노드 레포가 설치되지 않았거나
  • 업데이트로 노드 이름/입출력 포트가 변경

대응:

  1. 워크플로를 만든 환경의 custom_nodes 목록을 확인
  2. 동일한 커밋/버전으로 맞추기
  3. 그래도 안 되면 JSON에서 해당 노드 타입을 검색해 대체 노드로 수동 교체

6-2. API 프롬프트 JSON과 워크플로 JSON 혼동

ComfyUI는 “워크플로”와 “프롬프트(API용)” JSON의 키 구조가 다릅니다. 파일 상단에 nodes 배열이 없다면 워크플로가 아닐 수 있습니다.

jq 'keys' workflow.json
# nodes, links, groups 같은 키가 보이면 워크플로일 가능성이 큼

7) 자동 복구 파이프라인: 진단부터 수정까지 한 번에

아래는 실무적으로 자주 쓰는 흐름입니다.

  1. jq 파싱 실패면
    • 스마트 따옴표 치환
    • EOF 잘림이면 괄호 보정
    • 그래도 실패하면 마지막 라인/블록 절단
  2. jq 파싱 성공인데 ComfyUI 로드 실패면
    • 커스텀 노드 설치/버전 정렬
    • 문제 노드 타입 찾아 제거/대체

간단한 셸 파이프라인 예시:

set -euo pipefail

in=workflow.json
step1=workflow.step1.json
step2=workflow.step2.json

# 1) 스마트 따옴표 정리
python - <<'PY'
import sys
p=sys.argv[1]
out=sys.argv[2]
s=open(p,'r',encoding='utf-8',errors='replace').read()
s=s.replace('“','"').replace('”','"').replace('’',"'").replace('‘',"'")
open(out,'w',encoding='utf-8').write(s)
PY "$in" "$step1"

# 2) 괄호 보정
python - <<'PY'
import sys
src=open(sys.argv[1],'r',encoding='utf-8',errors='replace').read()
need_square=max(0, src.count('[')-src.count(']'))
need_curly=max(0, src.count('{')-src.count('}'))
fixed=src + (']'*need_square) + ('}'*need_curly)
open(sys.argv[2],'w',encoding='utf-8').write(fixed)
print('added ]',need_square,'added }',need_curly)
PY "$step1" "$step2"

# 3) 파싱 확인
jq . "$step2" > /dev/null
echo "Recovered JSON is parseable: $step2"

set -euo pipefail은 이런 “중간 실패를 즉시 감지”하는 자동화에 특히 유용합니다. 자세한 배경은 bash set -euo pipefail로 배포 스크립트 실패 잡기에서 더 깊게 다룹니다.

8) 재발 방지: 워크플로를 ‘아티팩트’로 관리하기

8-1. 저장 습관

  • 큰 변경 전후로 파일을 별도 이름으로 저장(스냅샷)
  • 원격 접속이면 네트워크 불안정 구간에서 저장/다운로드를 피하기

8-2. Git + 작은 커밋

워크플로도 코드처럼 다루면 복구 난이도가 급감합니다.

git add workflow.json
git commit -m "tune sampler and cfg"

8-3. 자동 백업(타임스탬프 복사)

mkdir -p backups
cp workflow.json "backups/workflow.$(date +%Y%m%d-%H%M%S).json"

8-4. 장애 대응 관점의 공통 원칙

JSON 깨짐 복구는 본질적으로 “원인 파악 → 최소 변경으로 정상화 → 재발 방지”의 루틴입니다. 이런 루틴은 인프라 장애에도 그대로 적용됩니다. 예를 들어 서비스가 반복 재시작하는 상황에서 원인을 좁히는 방법은 systemd 재시작 루프(StartLimitHit) 해결법도 같은 결을 갖습니다.

9) 체크리스트: 가장 빠른 복구 순서

  • jq . file.json으로 파싱 여부 확인
  • EOF 잘림이면 괄호 보정 스크립트 적용
  • 문자열 중간 잘림이면 마지막 블록 절단 후 재시도
  • 스마트 따옴표/복붙 흔적이 있으면 따옴표 치환
  • 파싱은 되는데 로딩이 안 되면 커스텀 노드/버전부터 맞추기
  • 복구 후에는 즉시 백업 및 Git 커밋

마무리

ComfyUI 워크플로 JSON 깨짐은 “한 번도 안 겪는 사람은 있어도, 한 번만 겪는 사람은 드문” 유형의 사고입니다. 중요한 건 완벽한 복원보다, 워크플로 구조를 다시 열 수 있는 상태로 빠르게 되돌리는 것입니다. 위의 진단(jq)과 2단계 복구(따옴표 정리, 괄호 보정), 그리고 최후의 수단(마지막 블록 절단)만 익혀도 대부분의 케이스는 시간 내 복구가 가능합니다.

다음에 같은 문제가 다시 생기지 않도록, 워크플로를 Git으로 관리하고 자동 백업을 붙이는 순간부터 복구는 ‘사건’이 아니라 ‘절차’가 됩니다.