Custom node failed

I’m creating a custom node (https://www.gumloop.com/custom-nodes/builder) to automatically generate slide decks using FlashDocs (https://docs.flashdocs.com/). It works when I run my code on my computer, but it returns an error:

Slide Decks Failed!
Command exited with code 1 and error:
Traceback (most recent call last):
File “/index.py”, line 32, in main
raise KeyError(“Task ID not found in API response”)
KeyError: ‘Task ID not found in API response’

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “/index.py”, line 72, in
print(‘FUNCTION_OUTPUT\n’ + str(main(‘Future of AI’, ‘eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJtb3J0ZW5AZmxhc2hkb2NzLmFpIiwib3JnYW5pemF0aW9uX2lkIjoiZmxhc2hkb2NzLmFpIiwiY2hlY2tfZXhwaXJlZCI6dHJ1ZSwiZXhwIjoxNzQ1MTU5OTgyfQ.wDQhyJDRyq9FsfJeGrEpDs7vnokYuShrH4-K1kAu1LI’, {})))
File “/index.py”, line 67, in main
raise Exception(f"Failed to extract required data: {str(e)}")
Exception: Failed to extract required data: ‘Task ID not found in API response’


Here’s the code I’m using:

def main(Prompt, API_key, params):
import requests
import json
import time

# API endpoint URLs
create_task_url = "https://api.flashdocs.ai/v3/generate/deck/task"

# Set up headers with API key
headers = {
    "Authorization": f"Bearer {API_key}",
    "Content-Type": "application/json"
}

# Set up request body with minimum required parameters
data = {
    "prompt": Prompt,
    "google_document_editors": []
}

try:
    # Make POST request to create task
    response = requests.post(create_task_url, headers=headers, data=json.dumps(data))
    
    # Check if request was successful
    response.raise_for_status()
    
    # Parse response JSON to get task ID
    task_data = response.json()
    
    if "id" not in task_data:
        raise KeyError("Task ID not found in API response")
        
    task_id = task_data["id"]
    
    # Poll status endpoint until complete
    poll_url = f"https://api.flashdocs.ai/v3/generate/deck/task/{task_id}"
    max_retries = 60  # Maximum number of retries (10 minutes with 10 second intervals)
    retries = 0
    
    while retries < max_retries:
        # Get task status
        status_response = requests.get(poll_url, headers=headers)
        status_response.raise_for_status()
        
        status_data = status_response.json()
        
        # If task is complete, return the URL
        if status_data.get("status") == "complete" and "url" in status_data:
            return status_data["url"]
            
        # If task failed, raise exception
        if status_data.get("status") == "failed":
            raise Exception("Task generation failed")
            
        # Wait before polling again
        time.sleep(10)
        retries += 1
        
    raise Exception("Task timed out")

except requests.exceptions.RequestException as e:
    raise Exception(f"API request failed: {str(e)}")
except json.JSONDecodeError:
    raise Exception("Failed to parse API response")
except KeyError as e:
    raise Exception(f"Failed to extract required data: {str(e)}")
except Exception as e:
    raise Exception(f"Error occurred: {str(e)}")

return Download_link

Hey @mortenator! If you’re reporting an issue with a flow or an error in a run, please include the run link and make sure it’s shareable so we can take a look.

  1. Find your run link on the history page. Format: https://www.gumloop.com/pipeline?run_id={your_run_id}&workbook_id={workbook_id}

  2. Make it shareable by clicking “Share” → ‘Anyone with the link can view’ in the top-left corner of the flow screen.
    GIF guide

  3. Provide details about the issue—more context helps us troubleshoot faster.

You can find your run history here: https://www.gumloop.com/history

Here’s the node: https://www.gumloop.com/custom-nodes/builder?node_id=fUnq1sep2vBbJ7cKCLDrsa

Hey @mortenator – That’s an interesting custom node (I’d like to try that as well - I signed-up on Flashdocs).

We usually don’t have the capacity to help with custom code since its highly personalized but I can help you troubleshoot here.

The main issue is that your code is looking for an “id” field in the API response, but it’s not finding it.

According to the documentation, when you call the /v3/generate/deck/task endpoint, the response includes a field called task_id (not id).

Can you try the following code:

def main(Prompt, API_key, params):
    import requests
    import json
    import time
    
    # API endpoint URLs
    create_task_url = "https://api.flashdocs.ai/v3/generate/deck/task"
    
    # Set up headers with API key
    headers = {
        "Authorization": f"Bearer {API_key}",
        "Content-Type": "application/json"
    }
    
    # Set up request body with minimum required parameters
    data = {
        "prompt": Prompt,
        "google_document_editors": []
    }
    
    # Make POST request to create task
    response = requests.post(create_task_url, headers=headers, data=json.dumps(data))
    response.raise_for_status()
    
    # Parse response JSON to get task ID
    task_data = response.json()
    task_id = task_data["task_id"]
    
    # Poll status endpoint until complete
    poll_url = f"https://api.flashdocs.ai/v3/generate/deck/task/{task_id}"
    max_retries = 60  # Maximum number of retries (10 minutes with 10 second intervals)
    retries = 0
    
    while retries < max_retries:
        # Get task status
        status_response = requests.get(poll_url, headers=headers)
        
        # If status code is 202, task is still processing
        if status_response.status_code == 202:
            time.sleep(10)
            retries += 1
            continue
            
        # If we got a 200, the task is complete
        status_response.raise_for_status()
        status_data = status_response.json()
        
        # If task is complete, return the URL
        if status_data.get("success") == True and "link_to_deck" in status_data:
            Download_link = status_data["link_to_deck"]
            return Download_link
            
        # If task failed, raise exception
        if status_data.get("success") == False:
            error_msg = status_data.get("error", "No error details provided")
            raise Exception(f"Task generation failed: {error_msg}")
            
        # Wait before polling again
        time.sleep(10)
        retries += 1
    
    raise Exception("Task timed out")

return Download_link

Let me know if this makes sense and works for you :slightly_smiling_face:

Hey @Wasay-Gumloop ! Thank you SO much for your help here - really appreciate it!

That did seem to solve the error, but now I’m getting a response saying: “Sorry something went wrong. Please email founders@gumloop.com to book a demo instead.”

I’ll send you an API key so you can try it out, too - I’m sure this is just a “me”-problem :wink:

I see. I tried running a prompt with the API key on your playground but it doesn’t output anything. Have you tried making this request in Postman? What do you get?

Hey @Wasay-Gumloop I think there was a bug which now has been fixed. When I try the following code in our playground it works:

import requests

url = “https://api.flashdocs.ai/v3/generate/deck

payload = {
“prompt”: “test”
}
headers = {
“Authorization”: “Bearer {API_KEY}”,
“Content-Type”: “application/json”
}

response = requests.request(“POST”, url, json=payload, headers=headers)

print(response.text)

Gotcha. It should now work with the custom node too – I tested again with my API key but can’t seem to run anything either on postman or your playground – once that is fixed you should be all set!

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.